blob: 9c5642c3ad679a0400fcc398697f7a97b7849698 [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,
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301105 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1106 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301107 return FALSE;
1108 }
1109
Mukul Sharmaf1bd9322015-10-20 16:03:42 +05301110#ifdef FEATURE_EXT_LL_STAT
1111 /*
1112 * Ensure when EXT_LL_STAT is supported by both host and fwr,
1113 * then host should send Leaky AP stats to upper layer,
1114 * otherwise no need to send these stats.
1115 */
1116 if(sme_IsFeatureSupportedByFW(EXT_LL_STAT) &&
1117 sme_IsFeatureSupportedByDriver(EXT_LL_STAT)
1118 )
1119 {
1120 hddLog(VOS_TRACE_LEVEL_INFO,
1121 FL("EXT_LL_STAT is supported by fwr and host %u %u %u %llu"),
1122 pWifiIfaceStat->leakyApStat.is_leaky_ap,
1123 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked,
1124 pWifiIfaceStat->leakyApStat.rx_leak_window,
1125 pWifiIfaceStat->leakyApStat.avg_bcn_spread);
1126 if (nla_put_u32(vendor_event,
1127 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_DETECTED,
1128 pWifiIfaceStat->leakyApStat.is_leaky_ap) ||
1129 nla_put_u32(vendor_event,
1130 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_AVG_NUM_FRAMES_LEAKED,
1131 pWifiIfaceStat->leakyApStat.avg_rx_frms_leaked) ||
1132 nla_put_u32(vendor_event,
1133 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_LEAKY_AP_GUARD_TIME,
1134 pWifiIfaceStat->leakyApStat.rx_leak_window) ||
1135 nla_put_u64(vendor_event,
1136 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_AVERAGE_TSF_OFFSET,
1137 pWifiIfaceStat->leakyApStat.avg_bcn_spread))
1138 {
1139 hddLog(VOS_TRACE_LEVEL_ERROR,
1140 FL("EXT_LL_STAT put fail"));
1141 vos_mem_free(pWifiIfaceStatTL);
1142 return FALSE;
1143 }
1144 }
1145#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301146 wmmInfo = nla_nest_start(vendor_event,
1147 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301148 if(!wmmInfo)
1149 {
1150 vos_mem_free(pWifiIfaceStatTL);
1151 return FALSE;
1152 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301153 for (i = 0; i < WIFI_AC_MAX; i++)
1154 {
1155 struct nlattr *wmmStats;
1156 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301157 if(!wmmStats)
1158 {
1159 vos_mem_free(pWifiIfaceStatTL);
1160 return FALSE;
1161 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301162 if (FALSE == put_wifi_wmm_ac_stat(
1163 &pWifiIfaceStat->AccessclassStats[i],
1164 vendor_event))
1165 {
1166 hddLog(VOS_TRACE_LEVEL_ERROR,
1167 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301168 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301169 return FALSE;
1170 }
1171
1172 nla_nest_end(vendor_event, wmmStats);
1173 }
1174 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301175 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301176 return TRUE;
1177}
1178
1179static tSirWifiInterfaceMode
1180 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1181{
1182 switch (deviceMode)
1183 {
1184 case WLAN_HDD_INFRA_STATION:
1185 return WIFI_INTERFACE_STA;
1186 case WLAN_HDD_SOFTAP:
1187 return WIFI_INTERFACE_SOFTAP;
1188 case WLAN_HDD_P2P_CLIENT:
1189 return WIFI_INTERFACE_P2P_CLIENT;
1190 case WLAN_HDD_P2P_GO:
1191 return WIFI_INTERFACE_P2P_GO;
1192 case WLAN_HDD_IBSS:
1193 return WIFI_INTERFACE_IBSS;
1194 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301195 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301196 }
1197}
1198
1199static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1200 tpSirWifiInterfaceInfo pInfo)
1201{
1202 v_U8_t *staMac = NULL;
1203 hdd_station_ctx_t *pHddStaCtx;
1204 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1205 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1206
1207 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1208
1209 vos_mem_copy(pInfo->macAddr,
1210 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1211
1212 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1213 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1214 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1215 {
1216 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1217 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1218 {
1219 pInfo->state = WIFI_DISCONNECTED;
1220 }
1221 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1222 {
1223 hddLog(VOS_TRACE_LEVEL_ERROR,
1224 "%s: Session ID %d, Connection is in progress", __func__,
1225 pAdapter->sessionId);
1226 pInfo->state = WIFI_ASSOCIATING;
1227 }
1228 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1229 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1230 {
1231 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1232 hddLog(VOS_TRACE_LEVEL_ERROR,
1233 "%s: client " MAC_ADDRESS_STR
1234 " is in the middle of WPS/EAPOL exchange.", __func__,
1235 MAC_ADDR_ARRAY(staMac));
1236 pInfo->state = WIFI_AUTHENTICATING;
1237 }
1238 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1239 {
1240 pInfo->state = WIFI_ASSOCIATED;
1241 vos_mem_copy(pInfo->bssid,
1242 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1243 vos_mem_copy(pInfo->ssid,
1244 pHddStaCtx->conn_info.SSID.SSID.ssId,
1245 pHddStaCtx->conn_info.SSID.SSID.length);
1246 //NULL Terminate the string.
1247 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1248 }
1249 }
1250 vos_mem_copy(pInfo->countryStr,
1251 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1252
1253 vos_mem_copy(pInfo->apCountryStr,
1254 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1255
1256 return TRUE;
1257}
1258
1259/*
1260 * hdd_link_layer_process_peer_stats () - This function is called after
1261 * receiving Link Layer Peer statistics from FW.This function converts
1262 * the firmware data to the NL data and sends the same to the kernel/upper
1263 * layers.
1264 */
1265static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1266 v_VOID_t *pData)
1267{
1268 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301269 tpSirWifiPeerStat pWifiPeerStat;
1270 tpSirWifiPeerInfo pWifiPeerInfo;
1271 struct nlattr *peerInfo;
1272 struct sk_buff *vendor_event;
1273 int status, i;
1274
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301275 ENTER();
1276
Sunil Duttc69bccb2014-05-26 21:30:20 +05301277 status = wlan_hdd_validate_context(pHddCtx);
1278 if (0 != status)
1279 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301280 return;
1281 }
1282
1283 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1284
1285 hddLog(VOS_TRACE_LEVEL_INFO,
1286 "LL_STATS_PEER_ALL : numPeers %u",
1287 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301288 /*
1289 * Allocate a size of 4096 for the peer stats comprising
1290 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1291 * sizeof (tSirWifiRateStat).Each field is put with an
1292 * NL attribute.The size of 4096 is considered assuming
1293 * that number of rates shall not exceed beyond 50 with
1294 * the sizeof (tSirWifiRateStat) being 32.
1295 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301296 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1297 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301298 if (!vendor_event)
1299 {
1300 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301301 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301302 __func__);
1303 return;
1304 }
1305 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301306 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1307 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1308 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301309 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1310 pWifiPeerStat->numPeers))
1311 {
1312 hddLog(VOS_TRACE_LEVEL_ERROR,
1313 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1314 kfree_skb(vendor_event);
1315 return;
1316 }
1317
1318 peerInfo = nla_nest_start(vendor_event,
1319 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301320 if(!peerInfo)
1321 {
1322 hddLog(VOS_TRACE_LEVEL_ERROR,
1323 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1324 __func__);
1325 kfree_skb(vendor_event);
1326 return;
1327 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301328
1329 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1330 pWifiPeerStat->peerInfo);
1331
1332 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1333 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301334 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301335 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301336
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301337 if(!peers)
1338 {
1339 hddLog(VOS_TRACE_LEVEL_ERROR,
1340 "%s: peer stats put fail",
1341 __func__);
1342 kfree_skb(vendor_event);
1343 return;
1344 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301345 if (FALSE == put_wifi_peer_info(
1346 pWifiPeerInfo, vendor_event))
1347 {
1348 hddLog(VOS_TRACE_LEVEL_ERROR,
1349 "%s: put_wifi_peer_info put fail", __func__);
1350 kfree_skb(vendor_event);
1351 return;
1352 }
1353
1354 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1355 pWifiPeerStat->peerInfo +
1356 (i * sizeof(tSirWifiPeerInfo)) +
1357 (numRate * sizeof (tSirWifiRateStat)));
1358 nla_nest_end(vendor_event, peers);
1359 }
1360 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301361 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301362 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301363}
1364
1365/*
1366 * hdd_link_layer_process_iface_stats () - This function is called after
1367 * receiving Link Layer Interface statistics from FW.This function converts
1368 * the firmware data to the NL data and sends the same to the kernel/upper
1369 * layers.
1370 */
1371static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1372 v_VOID_t *pData)
1373{
1374 tpSirWifiIfaceStat pWifiIfaceStat;
1375 struct sk_buff *vendor_event;
1376 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1377 int status;
1378
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301379 ENTER();
1380
Sunil Duttc69bccb2014-05-26 21:30:20 +05301381 status = wlan_hdd_validate_context(pHddCtx);
1382 if (0 != status)
1383 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301384 return;
1385 }
1386 /*
1387 * Allocate a size of 4096 for the interface stats comprising
1388 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1389 * assuming that all these fit with in the limit.Please take
1390 * a call on the limit based on the data requirements on
1391 * interface statistics.
1392 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301393 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1394 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301395 if (!vendor_event)
1396 {
1397 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301398 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301399 return;
1400 }
1401
1402 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1403
Dino Mycle3b9536d2014-07-09 22:05:24 +05301404
1405 if (FALSE == hdd_get_interface_info( pAdapter,
1406 &pWifiIfaceStat->info))
1407 {
1408 hddLog(VOS_TRACE_LEVEL_ERROR,
1409 FL("hdd_get_interface_info get fail") );
1410 kfree_skb(vendor_event);
1411 return;
1412 }
1413
1414 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1415 vendor_event))
1416 {
1417 hddLog(VOS_TRACE_LEVEL_ERROR,
1418 FL("put_wifi_iface_stats fail") );
1419 kfree_skb(vendor_event);
1420 return;
1421 }
1422
Sunil Duttc69bccb2014-05-26 21:30:20 +05301423 hddLog(VOS_TRACE_LEVEL_INFO,
1424 "WMI_LINK_STATS_IFACE Data");
1425
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301426 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301427
1428 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301429}
1430
1431/*
1432 * hdd_link_layer_process_radio_stats () - This function is called after
1433 * receiving Link Layer Radio statistics from FW.This function converts
1434 * the firmware data to the NL data and sends the same to the kernel/upper
1435 * layers.
1436 */
1437static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1438 v_VOID_t *pData)
1439{
1440 int status, i;
1441 tpSirWifiRadioStat pWifiRadioStat;
1442 tpSirWifiChannelStats pWifiChannelStats;
1443 struct sk_buff *vendor_event;
1444 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1445 struct nlattr *chList;
1446
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301447 ENTER();
1448
Sunil Duttc69bccb2014-05-26 21:30:20 +05301449 status = wlan_hdd_validate_context(pHddCtx);
1450 if (0 != status)
1451 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301452 return;
1453 }
1454 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1455
1456 hddLog(VOS_TRACE_LEVEL_INFO,
1457 "LL_STATS_RADIO"
1458 " radio is %d onTime is %u "
1459 " txTime is %u rxTime is %u "
1460 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301461 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301462 " onTimePnoScan is %u onTimeHs20 is %u "
1463 " numChannels is %u",
1464 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1465 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1466 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301467 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301468 pWifiRadioStat->onTimeRoamScan,
1469 pWifiRadioStat->onTimePnoScan,
1470 pWifiRadioStat->onTimeHs20,
1471 pWifiRadioStat->numChannels);
1472 /*
1473 * Allocate a size of 4096 for the Radio stats comprising
1474 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1475 * (tSirWifiChannelStats).Each channel data is put with an
1476 * NL attribute.The size of 4096 is considered assuming that
1477 * number of channels shall not exceed beyond 60 with the
1478 * sizeof (tSirWifiChannelStats) being 24 bytes.
1479 */
1480
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301481 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1482 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301483 if (!vendor_event)
1484 {
1485 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301486 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301487 return;
1488 }
1489
1490 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301491 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1492 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1493 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301494 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1495 pWifiRadioStat->radio) ||
1496 nla_put_u32(vendor_event,
1497 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1498 pWifiRadioStat->onTime) ||
1499 nla_put_u32(vendor_event,
1500 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1501 pWifiRadioStat->txTime) ||
1502 nla_put_u32(vendor_event,
1503 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1504 pWifiRadioStat->rxTime) ||
1505 nla_put_u32(vendor_event,
1506 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1507 pWifiRadioStat->onTimeScan) ||
1508 nla_put_u32(vendor_event,
1509 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1510 pWifiRadioStat->onTimeNbd) ||
1511 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301512 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1513 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301514 nla_put_u32(vendor_event,
1515 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1516 pWifiRadioStat->onTimeRoamScan) ||
1517 nla_put_u32(vendor_event,
1518 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1519 pWifiRadioStat->onTimePnoScan) ||
1520 nla_put_u32(vendor_event,
1521 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1522 pWifiRadioStat->onTimeHs20) ||
1523 nla_put_u32(vendor_event,
1524 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1525 pWifiRadioStat->numChannels))
1526 {
1527 hddLog(VOS_TRACE_LEVEL_ERROR,
1528 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1529 kfree_skb(vendor_event);
1530 return ;
1531 }
1532
1533 chList = nla_nest_start(vendor_event,
1534 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301535 if(!chList)
1536 {
1537 hddLog(VOS_TRACE_LEVEL_ERROR,
1538 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1539 __func__);
1540 kfree_skb(vendor_event);
1541 return;
1542 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301543 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1544 {
1545 struct nlattr *chInfo;
1546
1547 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1548 pWifiRadioStat->channels +
1549 (i * sizeof(tSirWifiChannelStats)));
1550
Sunil Duttc69bccb2014-05-26 21:30:20 +05301551 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301552 if(!chInfo)
1553 {
1554 hddLog(VOS_TRACE_LEVEL_ERROR,
1555 "%s: failed to put chInfo",
1556 __func__);
1557 kfree_skb(vendor_event);
1558 return;
1559 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301560
1561 if (nla_put_u32(vendor_event,
1562 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1563 pWifiChannelStats->channel.width) ||
1564 nla_put_u32(vendor_event,
1565 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1566 pWifiChannelStats->channel.centerFreq) ||
1567 nla_put_u32(vendor_event,
1568 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1569 pWifiChannelStats->channel.centerFreq0) ||
1570 nla_put_u32(vendor_event,
1571 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1572 pWifiChannelStats->channel.centerFreq1) ||
1573 nla_put_u32(vendor_event,
1574 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1575 pWifiChannelStats->onTime) ||
1576 nla_put_u32(vendor_event,
1577 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1578 pWifiChannelStats->ccaBusyTime))
1579 {
1580 hddLog(VOS_TRACE_LEVEL_ERROR,
1581 FL("cfg80211_vendor_event_alloc failed") );
1582 kfree_skb(vendor_event);
1583 return ;
1584 }
1585 nla_nest_end(vendor_event, chInfo);
1586 }
1587 nla_nest_end(vendor_event, chList);
1588
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301589 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301590
1591 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301592 return;
1593}
1594
1595/*
1596 * hdd_link_layer_stats_ind_callback () - This function is called after
1597 * receiving Link Layer indications from FW.This callback converts the firmware
1598 * data to the NL data and send the same to the kernel/upper layers.
1599 */
1600static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1601 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301602 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301603{
Dino Mycled3d50022014-07-07 12:58:25 +05301604 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1605 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301606 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301607 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301608 int status;
1609
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301610 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301611
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301612 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301613 if (0 != status)
1614 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301615 return;
1616 }
1617
Dino Mycled3d50022014-07-07 12:58:25 +05301618 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1619 if (NULL == pAdapter)
1620 {
1621 hddLog(VOS_TRACE_LEVEL_ERROR,
1622 FL(" MAC address %pM does not exist with host"),
1623 macAddr);
1624 return;
1625 }
1626
Sunil Duttc69bccb2014-05-26 21:30:20 +05301627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301628 "%s: Interface: %s LLStats indType: %d", __func__,
1629 pAdapter->dev->name, indType);
1630
Sunil Duttc69bccb2014-05-26 21:30:20 +05301631 switch (indType)
1632 {
1633 case SIR_HAL_LL_STATS_RESULTS_RSP:
1634 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301635 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301636 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
1637 "respId = %u, moreResultToFollow = %u",
1638 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
1639 macAddr, linkLayerStatsResults->respId,
1640 linkLayerStatsResults->moreResultToFollow);
1641
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301642 spin_lock(&hdd_context_lock);
1643 context = &pHddCtx->ll_stats_context;
1644 /* validate response received from target */
1645 if ((context->request_id != linkLayerStatsResults->respId) ||
1646 !(context->request_bitmap & linkLayerStatsResults->paramId))
1647 {
1648 spin_unlock(&hdd_context_lock);
1649 hddLog(LOGE,
1650 FL("Error : Request id %d response id %d request bitmap 0x%x"
1651 "response bitmap 0x%x"),
1652 context->request_id, linkLayerStatsResults->respId,
1653 context->request_bitmap, linkLayerStatsResults->paramId);
1654 return;
1655 }
1656 spin_unlock(&hdd_context_lock);
1657
Sunil Duttc69bccb2014-05-26 21:30:20 +05301658 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1659 {
1660 hdd_link_layer_process_radio_stats(pAdapter,
1661 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301662 spin_lock(&hdd_context_lock);
1663 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1664 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301665 }
1666 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1667 {
1668 hdd_link_layer_process_iface_stats(pAdapter,
1669 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301670 spin_lock(&hdd_context_lock);
1671 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1672 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301673 }
1674 else if ( linkLayerStatsResults->paramId &
1675 WMI_LINK_STATS_ALL_PEER )
1676 {
1677 hdd_link_layer_process_peer_stats(pAdapter,
1678 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301679 spin_lock(&hdd_context_lock);
1680 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1681 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301682 } /* WMI_LINK_STATS_ALL_PEER */
1683 else
1684 {
1685 hddLog(VOS_TRACE_LEVEL_ERROR,
1686 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1687 }
1688
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301689 spin_lock(&hdd_context_lock);
1690 /* complete response event if all requests are completed */
1691 if (0 == context->request_bitmap)
1692 complete(&context->response_event);
1693 spin_unlock(&hdd_context_lock);
1694
Sunil Duttc69bccb2014-05-26 21:30:20 +05301695 break;
1696 }
1697 default:
1698 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1699 break;
1700 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301701
1702 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301703 return;
1704}
1705
1706const struct
1707nla_policy
1708qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1709{
1710 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1711 { .type = NLA_U32 },
1712 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1713 { .type = NLA_U32 },
1714};
1715
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301716static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1717 struct wireless_dev *wdev,
1718 const void *data,
1719 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301720{
1721 int status;
1722 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301723 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301724 struct net_device *dev = wdev->netdev;
1725 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1726 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1727
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301728 ENTER();
1729
Sunil Duttc69bccb2014-05-26 21:30:20 +05301730 status = wlan_hdd_validate_context(pHddCtx);
1731 if (0 != status)
1732 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301733 return -EINVAL;
1734 }
1735
1736 if (NULL == pAdapter)
1737 {
1738 hddLog(VOS_TRACE_LEVEL_ERROR,
1739 FL("HDD adapter is Null"));
1740 return -ENODEV;
1741 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301742 /* check the LLStats Capability */
1743 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1744 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1745 {
1746 hddLog(VOS_TRACE_LEVEL_ERROR,
1747 FL("Link Layer Statistics not supported by Firmware"));
1748 return -EINVAL;
1749 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301750
1751 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1752 (struct nlattr *)data,
1753 data_len, qca_wlan_vendor_ll_set_policy))
1754 {
1755 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1756 return -EINVAL;
1757 }
1758 if (!tb_vendor
1759 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1760 {
1761 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1762 return -EINVAL;
1763 }
1764 if (!tb_vendor[
1765 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1766 {
1767 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1768 return -EINVAL;
1769 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301770 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301771 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301772
Dino Mycledf0a5d92014-07-04 09:41:55 +05301773 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301774 nla_get_u32(
1775 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1776
Dino Mycledf0a5d92014-07-04 09:41:55 +05301777 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301778 nla_get_u32(
1779 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1780
Dino Mycled3d50022014-07-07 12:58:25 +05301781 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1782 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301783
1784
1785 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301786 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
1787 "Statistics Gathering = %d ",
1788 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
1789 linkLayerStatsSetReq.mpduSizeThreshold,
1790 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301791
1792 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1793 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301794 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301795 {
1796 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1797 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301798 return -EINVAL;
1799
1800 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301801
Sunil Duttc69bccb2014-05-26 21:30:20 +05301802 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301803 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301804 {
1805 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1806 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301807 return -EINVAL;
1808 }
1809
1810 pAdapter->isLinkLayerStatsSet = 1;
1811
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301812 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301813 return 0;
1814}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301815static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1816 struct wireless_dev *wdev,
1817 const void *data,
1818 int data_len)
1819{
1820 int ret = 0;
1821
1822 vos_ssr_protect(__func__);
1823 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1824 vos_ssr_unprotect(__func__);
1825
1826 return ret;
1827}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301828
1829const struct
1830nla_policy
1831qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1832{
1833 /* Unsigned 32bit value provided by the caller issuing the GET stats
1834 * command. When reporting
1835 * the stats results, the driver uses the same value to indicate
1836 * which GET request the results
1837 * correspond to.
1838 */
1839 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1840
1841 /* Unsigned 32bit value . bit mask to identify what statistics are
1842 requested for retrieval */
1843 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1844};
1845
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301846static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1847 struct wireless_dev *wdev,
1848 const void *data,
1849 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301850{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301851 unsigned long rc;
1852 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301853 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1854 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301855 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301856 struct net_device *dev = wdev->netdev;
1857 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301858 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301859 int status;
1860
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301861 ENTER();
1862
Sunil Duttc69bccb2014-05-26 21:30:20 +05301863 status = wlan_hdd_validate_context(pHddCtx);
1864 if (0 != status)
1865 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301866 return -EINVAL ;
1867 }
1868
1869 if (NULL == pAdapter)
1870 {
1871 hddLog(VOS_TRACE_LEVEL_FATAL,
1872 "%s: HDD adapter is Null", __func__);
1873 return -ENODEV;
1874 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05301875
1876 if (pHddStaCtx == NULL)
1877 {
1878 hddLog(VOS_TRACE_LEVEL_FATAL,
1879 "%s: HddStaCtx is Null", __func__);
1880 return -ENODEV;
1881 }
1882
Dino Mycledf0a5d92014-07-04 09:41:55 +05301883 /* check the LLStats Capability */
1884 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1885 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1886 {
1887 hddLog(VOS_TRACE_LEVEL_ERROR,
1888 FL("Link Layer Statistics not supported by Firmware"));
1889 return -EINVAL;
1890 }
1891
Sunil Duttc69bccb2014-05-26 21:30:20 +05301892
1893 if (!pAdapter->isLinkLayerStatsSet)
1894 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05301895 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301896 "%s: isLinkLayerStatsSet : %d",
1897 __func__, pAdapter->isLinkLayerStatsSet);
1898 return -EINVAL;
1899 }
1900
Mukul Sharma10313ba2015-07-29 19:14:39 +05301901 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
1902 {
1903 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1904 "%s: Roaming in progress, so unable to proceed this request", __func__);
1905 return -EBUSY;
1906 }
1907
Sunil Duttc69bccb2014-05-26 21:30:20 +05301908 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1909 (struct nlattr *)data,
1910 data_len, qca_wlan_vendor_ll_get_policy))
1911 {
1912 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1913 return -EINVAL;
1914 }
1915
1916 if (!tb_vendor
1917 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1918 {
1919 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1920 return -EINVAL;
1921 }
1922
1923 if (!tb_vendor
1924 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1925 {
1926 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1927 return -EINVAL;
1928 }
1929
Sunil Duttc69bccb2014-05-26 21:30:20 +05301930
Dino Mycledf0a5d92014-07-04 09:41:55 +05301931 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301932 nla_get_u32( tb_vendor[
1933 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301934 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301935 nla_get_u32( tb_vendor[
1936 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1937
Dino Mycled3d50022014-07-07 12:58:25 +05301938 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1939 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301940
1941 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301942 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
1943 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301944 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301945
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301946 spin_lock(&hdd_context_lock);
1947 context = &pHddCtx->ll_stats_context;
1948 context->request_id = linkLayerStatsGetReq.reqId;
1949 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
1950 INIT_COMPLETION(context->response_event);
1951 spin_unlock(&hdd_context_lock);
1952
Sunil Duttc69bccb2014-05-26 21:30:20 +05301953 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301954 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301955 {
1956 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1957 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301958 return -EINVAL;
1959 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301960
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301961 rc = wait_for_completion_timeout(&context->response_event,
1962 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
1963 if (!rc)
1964 {
1965 hddLog(LOGE,
1966 FL("Target response timed out request id %d request bitmap 0x%x"),
1967 context->request_id, context->request_bitmap);
1968 return -ETIMEDOUT;
1969 }
1970
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301971 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301972 return 0;
1973}
1974
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301975static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1976 struct wireless_dev *wdev,
1977 const void *data,
1978 int data_len)
1979{
1980 int ret = 0;
1981
1982 vos_ssr_protect(__func__);
1983 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1984 vos_ssr_unprotect(__func__);
1985
1986 return ret;
1987}
1988
Sunil Duttc69bccb2014-05-26 21:30:20 +05301989const struct
1990nla_policy
1991qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1992{
1993 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1994 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1995 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1996 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1997};
1998
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301999static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2000 struct wireless_dev *wdev,
2001 const void *data,
2002 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302003{
2004 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2005 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302006 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302007 struct net_device *dev = wdev->netdev;
2008 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2009 u32 statsClearReqMask;
2010 u8 stopReq;
2011 int status;
2012
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302013 ENTER();
2014
Sunil Duttc69bccb2014-05-26 21:30:20 +05302015 status = wlan_hdd_validate_context(pHddCtx);
2016 if (0 != status)
2017 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302018 return -EINVAL;
2019 }
2020
2021 if (NULL == pAdapter)
2022 {
2023 hddLog(VOS_TRACE_LEVEL_FATAL,
2024 "%s: HDD adapter is Null", __func__);
2025 return -ENODEV;
2026 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302027 /* check the LLStats Capability */
2028 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2029 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2030 {
2031 hddLog(VOS_TRACE_LEVEL_ERROR,
2032 FL("Enable LLStats Capability"));
2033 return -EINVAL;
2034 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302035
2036 if (!pAdapter->isLinkLayerStatsSet)
2037 {
2038 hddLog(VOS_TRACE_LEVEL_FATAL,
2039 "%s: isLinkLayerStatsSet : %d",
2040 __func__, pAdapter->isLinkLayerStatsSet);
2041 return -EINVAL;
2042 }
2043
2044 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2045 (struct nlattr *)data,
2046 data_len, qca_wlan_vendor_ll_clr_policy))
2047 {
2048 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2049 return -EINVAL;
2050 }
2051
2052 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2053
2054 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2055 {
2056 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2057 return -EINVAL;
2058
2059 }
2060
Sunil Duttc69bccb2014-05-26 21:30:20 +05302061
Dino Mycledf0a5d92014-07-04 09:41:55 +05302062 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302063 nla_get_u32(
2064 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2065
Dino Mycledf0a5d92014-07-04 09:41:55 +05302066 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302067 nla_get_u8(
2068 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2069
2070 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302071 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302072
Dino Mycled3d50022014-07-07 12:58:25 +05302073 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2074 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302075
2076 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302077 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2078 "statsClearReqMask = 0x%X, stopReq = %d",
2079 linkLayerStatsClearReq.reqId,
2080 linkLayerStatsClearReq.macAddr,
2081 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302082 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302083
2084 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302085 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302086 {
2087 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302088 hdd_station_ctx_t *pHddStaCtx;
2089
2090 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2091 if (VOS_STATUS_SUCCESS !=
2092 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2093 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2094 {
2095 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2096 "WLANTL_ClearInterfaceStats Failed", __func__);
2097 return -EINVAL;
2098 }
2099 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2100 (statsClearReqMask & WIFI_STATS_IFACE)) {
2101 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2102 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2103 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2104 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2105 }
2106
Sunil Duttc69bccb2014-05-26 21:30:20 +05302107 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2108 2 * sizeof(u32) +
2109 NLMSG_HDRLEN);
2110
2111 if (temp_skbuff != NULL)
2112 {
2113
2114 if (nla_put_u32(temp_skbuff,
2115 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2116 statsClearReqMask) ||
2117 nla_put_u32(temp_skbuff,
2118 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2119 stopReq))
2120 {
2121 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2122 kfree_skb(temp_skbuff);
2123 return -EINVAL;
2124 }
2125 /* If the ask is to stop the stats collection as part of clear
2126 * (stopReq = 1) , ensure that no further requests of get
2127 * go to the firmware by having isLinkLayerStatsSet set to 0.
2128 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302129 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302130 * case the firmware is just asked to clear the statistics.
2131 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302132 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302133 pAdapter->isLinkLayerStatsSet = 0;
2134 return cfg80211_vendor_cmd_reply(temp_skbuff);
2135 }
2136 return -ENOMEM;
2137 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302138
2139 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302140 return -EINVAL;
2141}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302142static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2143 struct wireless_dev *wdev,
2144 const void *data,
2145 int data_len)
2146{
2147 int ret = 0;
2148
2149 vos_ssr_protect(__func__);
2150 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2151 vos_ssr_unprotect(__func__);
2152
2153 return ret;
2154
2155
2156}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302157#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2158
Dino Mycle6fb96c12014-06-10 11:52:40 +05302159#ifdef WLAN_FEATURE_EXTSCAN
2160static const struct nla_policy
2161wlan_hdd_extscan_config_policy
2162 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2163{
2164 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2165 { .type = NLA_U32 },
2166 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2167 { .type = NLA_U32 },
2168 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2169 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2170 { .type = NLA_U32 },
2171 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2172 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2173
2174 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2175 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2176 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2177 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2178 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302179 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2180 { .type = NLA_U32 },
2181 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2182 { .type = NLA_U32 },
2183 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2184 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302185 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2186 { .type = NLA_U32 },
2187 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2188 { .type = NLA_U32 },
2189 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2190 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302191 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2192 { .type = NLA_U8 },
2193 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302194 { .type = NLA_U8 },
2195 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2196 { .type = NLA_U8 },
2197 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2198 { .type = NLA_U8 },
2199
2200 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2201 { .type = NLA_U32 },
2202 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2203 { .type = NLA_UNSPEC },
2204 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2205 { .type = NLA_S32 },
2206 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2207 { .type = NLA_S32 },
2208 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2209 { .type = NLA_U32 },
2210 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2211 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302212 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2213 { .type = NLA_U32 },
2214 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2215 { .type = NLA_BINARY,
2216 .len = IEEE80211_MAX_SSID_LEN + 1 },
2217 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302218 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302219 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2220 { .type = NLA_U32 },
2221 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2222 { .type = NLA_U8 },
2223 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2224 { .type = NLA_S32 },
2225 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2226 { .type = NLA_S32 },
2227 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2228 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302229};
2230
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302231/**
2232 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2233 * @ctx: hdd global context
2234 * @data: capabilities data
2235 *
2236 * Return: none
2237 */
2238static void
2239wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302240{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302241 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302242 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302243 tSirEXTScanCapabilitiesEvent *data =
2244 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302245
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302246 ENTER();
2247
2248 if (wlan_hdd_validate_context(pHddCtx))
2249 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302250 return;
2251 }
2252
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302253 if (!pMsg)
2254 {
2255 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2256 return;
2257 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302258
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302259 vos_spin_lock_acquire(&hdd_context_lock);
2260
2261 context = &pHddCtx->ext_scan_context;
2262 /* validate response received from target*/
2263 if (context->request_id != data->requestId)
2264 {
2265 vos_spin_lock_release(&hdd_context_lock);
2266 hddLog(LOGE,
2267 FL("Target response id did not match: request_id %d resposne_id %d"),
2268 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302269 return;
2270 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302271 else
2272 {
2273 context->capability_response = *data;
2274 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302275 }
2276
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302277 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302278
Dino Mycle6fb96c12014-06-10 11:52:40 +05302279 return;
2280}
2281
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302282/*
2283 * define short names for the global vendor params
2284 * used by wlan_hdd_send_ext_scan_capability()
2285 */
2286#define PARAM_REQUEST_ID \
2287 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2288#define PARAM_STATUS \
2289 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2290#define MAX_SCAN_CACHE_SIZE \
2291 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2292#define MAX_SCAN_BUCKETS \
2293 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2294#define MAX_AP_CACHE_PER_SCAN \
2295 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2296#define MAX_RSSI_SAMPLE_SIZE \
2297 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2298#define MAX_SCAN_RPT_THRHOLD \
2299 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2300#define MAX_HOTLIST_BSSIDS \
2301 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2302#define MAX_BSSID_HISTORY_ENTRIES \
2303 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2304#define MAX_HOTLIST_SSIDS \
2305 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302306#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2307 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302308
2309static int wlan_hdd_send_ext_scan_capability(void *ctx)
2310{
2311 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2312 struct sk_buff *skb = NULL;
2313 int ret;
2314 tSirEXTScanCapabilitiesEvent *data;
2315 tANI_U32 nl_buf_len;
2316
2317 ret = wlan_hdd_validate_context(pHddCtx);
2318 if (0 != ret)
2319 {
2320 return ret;
2321 }
2322
2323 data = &(pHddCtx->ext_scan_context.capability_response);
2324
2325 nl_buf_len = NLMSG_HDRLEN;
2326 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2327 (sizeof(data->status) + NLA_HDRLEN) +
2328 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2329 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2330 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2331 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2332 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2333 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2334 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2335 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2336
2337 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2338
2339 if (!skb)
2340 {
2341 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2342 return -ENOMEM;
2343 }
2344
2345 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2346 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2347 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2348 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2349 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2350 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2351 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2352 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2353
2354 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2355 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2356 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2357 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2358 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2359 data->maxApPerScan) ||
2360 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2361 data->maxRssiSampleSize) ||
2362 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2363 data->maxScanReportingThreshold) ||
2364 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2365 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2366 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302367 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2368 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302369 {
2370 hddLog(LOGE, FL("nla put fail"));
2371 goto nla_put_failure;
2372 }
2373
2374 cfg80211_vendor_cmd_reply(skb);
2375 return 0;
2376
2377nla_put_failure:
2378 kfree_skb(skb);
2379 return -EINVAL;;
2380}
2381
2382/*
2383 * done with short names for the global vendor params
2384 * used by wlan_hdd_send_ext_scan_capability()
2385 */
2386#undef PARAM_REQUEST_ID
2387#undef PARAM_STATUS
2388#undef MAX_SCAN_CACHE_SIZE
2389#undef MAX_SCAN_BUCKETS
2390#undef MAX_AP_CACHE_PER_SCAN
2391#undef MAX_RSSI_SAMPLE_SIZE
2392#undef MAX_SCAN_RPT_THRHOLD
2393#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302394#undef MAX_BSSID_HISTORY_ENTRIES
2395#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302396
2397static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2398{
2399 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2400 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302401 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302402 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302403
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302404 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302405
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302406 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302407 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302408
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302409 if (!pMsg)
2410 {
2411 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302412 return;
2413 }
2414
Dino Mycle6fb96c12014-06-10 11:52:40 +05302415 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2416 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2417
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302418 context = &pHddCtx->ext_scan_context;
2419 spin_lock(&hdd_context_lock);
2420 if (context->request_id == pData->requestId) {
2421 context->response_status = pData->status ? -EINVAL : 0;
2422 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302423 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302424 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302425
2426 /*
2427 * Store the Request ID for comparing with the requestID obtained
2428 * in other requests.HDD shall return a failure is the extscan_stop
2429 * request is issued with a different requestId as that of the
2430 * extscan_start request. Also, This requestId shall be used while
2431 * indicating the full scan results to the upper layers.
2432 * The requestId is stored with the assumption that the firmware
2433 * shall return the ext scan start request's requestId in ext scan
2434 * start response.
2435 */
2436 if (pData->status == 0)
2437 pMac->sme.extScanStartReqId = pData->requestId;
2438
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302439 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302440 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302441}
2442
2443
2444static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2445{
2446 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2447 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302448 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302449
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302450 ENTER();
2451
2452 if (wlan_hdd_validate_context(pHddCtx)){
2453 return;
2454 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302455
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302456 if (!pMsg)
2457 {
2458 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302459 return;
2460 }
2461
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302462 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2463 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302464
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302465 context = &pHddCtx->ext_scan_context;
2466 spin_lock(&hdd_context_lock);
2467 if (context->request_id == pData->requestId) {
2468 context->response_status = pData->status ? -EINVAL : 0;
2469 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302470 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302471 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302472
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302473 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302474 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302475}
2476
Dino Mycle6fb96c12014-06-10 11:52:40 +05302477static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2478 void *pMsg)
2479{
2480 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302481 tpSirEXTScanSetBssidHotListRspParams pData =
2482 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302483 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302484
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302485 ENTER();
2486
2487 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302488 return;
2489 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302490
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302491 if (!pMsg)
2492 {
2493 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2494 return;
2495 }
2496
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302497 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2498 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302499
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302500 context = &pHddCtx->ext_scan_context;
2501 spin_lock(&hdd_context_lock);
2502 if (context->request_id == pData->requestId) {
2503 context->response_status = pData->status ? -EINVAL : 0;
2504 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302505 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302506 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302507
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302508 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302509 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302510}
2511
2512static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2513 void *pMsg)
2514{
2515 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302516 tpSirEXTScanResetBssidHotlistRspParams pData =
2517 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302518 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302519
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302520 ENTER();
2521
2522 if (wlan_hdd_validate_context(pHddCtx)) {
2523 return;
2524 }
2525 if (!pMsg)
2526 {
2527 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302528 return;
2529 }
2530
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302531 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2532 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302533
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302534 context = &pHddCtx->ext_scan_context;
2535 spin_lock(&hdd_context_lock);
2536 if (context->request_id == pData->requestId) {
2537 context->response_status = pData->status ? -EINVAL : 0;
2538 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302539 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302540 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302541
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302542 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302543 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302544}
2545
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302546static void wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(void *ctx,
2547 void *pMsg)
2548{
2549 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2550 tpSirEXTScanSetSsidHotListRspParams pData =
2551 (tpSirEXTScanSetSsidHotListRspParams) pMsg;
2552 struct hdd_ext_scan_context *context;
2553
2554 if (wlan_hdd_validate_context(pHddCtx)){
2555 return;
2556 }
2557
2558 if (!pMsg)
2559 {
2560 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2561 return;
2562 }
2563
2564 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2565 pData->status);
2566
2567 context = &pHddCtx->ext_scan_context;
2568 spin_lock(&hdd_context_lock);
2569 if (context->request_id == pData->requestId) {
2570 context->response_status = pData->status ? -EINVAL : 0;
2571 complete(&context->response_event);
2572 }
2573 spin_unlock(&hdd_context_lock);
2574
2575 return;
2576}
2577
2578static void wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(void *ctx,
2579 void *pMsg)
2580{
2581 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2582 tpSirEXTScanResetSsidHotlistRspParams pData =
2583 (tpSirEXTScanResetSsidHotlistRspParams) pMsg;
2584 struct hdd_ext_scan_context *context;
2585
2586 if (wlan_hdd_validate_context(pHddCtx)) {
2587 return;
2588 }
2589 if (!pMsg)
2590 {
2591 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2592 return;
2593 }
2594
2595 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2596 pData->status);
2597
2598 context = &pHddCtx->ext_scan_context;
2599 spin_lock(&hdd_context_lock);
2600 if (context->request_id == pData->requestId) {
2601 context->response_status = pData->status ? -EINVAL : 0;
2602 complete(&context->response_event);
2603 }
2604 spin_unlock(&hdd_context_lock);
2605
2606 return;
2607}
2608
2609
Dino Mycle6fb96c12014-06-10 11:52:40 +05302610static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2611 void *pMsg)
2612{
2613 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2614 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302615 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302616 tANI_S32 totalResults;
2617 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302618 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
2619 struct hdd_ext_scan_context *context;
2620 bool ignore_cached_results = false;
2621 tExtscanCachedScanResult *result;
2622 struct nlattr *nla_results;
2623 tANI_U16 ieLength= 0;
2624 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302625
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302626 ENTER();
2627
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302628 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302629 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302630
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302631 if (!pMsg)
2632 {
2633 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2634 return;
2635 }
2636
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302637 spin_lock(&hdd_context_lock);
2638 context = &pHddCtx->ext_scan_context;
2639 ignore_cached_results = context->ignore_cached_results;
2640 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302641
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302642 if (ignore_cached_results) {
2643 hddLog(LOGE,
2644 FL("Ignore the cached results received after timeout"));
2645 return;
2646 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302647
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302648 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
2649 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302650
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302651 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302652
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302653 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
2654 scan_id_index++) {
2655 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302656
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302657 totalResults = result->num_results;
2658 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
2659 result->scan_id, result->flags, totalResults);
2660 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302661
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302662 do{
2663 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2664 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2665 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302666
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302667 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2668 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
2669
2670 if (!skb) {
2671 hddLog(VOS_TRACE_LEVEL_ERROR,
2672 FL("cfg80211_vendor_event_alloc failed"));
2673 return;
2674 }
2675
2676 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2677
2678 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2679 pData->requestId) ||
2680 nla_put_u32(skb,
2681 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2682 resultsPerEvent)) {
2683 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2684 goto fail;
2685 }
2686 if (nla_put_u8(skb,
2687 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2688 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302689 {
2690 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2691 goto fail;
2692 }
2693
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302694 if (nla_put_u32(skb,
2695 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2696 result->scan_id)) {
2697 hddLog(LOGE, FL("put fail"));
2698 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302699 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302700
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302701 nla_results = nla_nest_start(skb,
2702 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
2703 if (!nla_results)
2704 goto fail;
2705
2706 if (resultsPerEvent) {
2707 struct nlattr *aps;
2708 struct nlattr *nla_result;
2709
2710 nla_result = nla_nest_start(skb, scan_id_index);
2711 if(!nla_result)
2712 goto fail;
2713
2714 if (nla_put_u32(skb,
2715 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2716 result->scan_id) ||
2717 nla_put_u32(skb,
2718 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
2719 result->flags) ||
2720 nla_put_u32(skb,
2721 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2722 totalResults)) {
2723 hddLog(LOGE, FL("put fail"));
2724 goto fail;
2725 }
2726
2727 aps = nla_nest_start(skb,
2728 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2729 if (!aps)
2730 {
2731 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2732 goto fail;
2733 }
2734
2735 head_ptr = (tpSirWifiScanResult) &(result->ap);
2736
2737 for (j = 0; j < resultsPerEvent; j++, i++) {
2738 struct nlattr *ap;
2739 pSirWifiScanResult = head_ptr + i;
2740
2741 /*
2742 * Firmware returns timestamp from WiFi turn ON till
2743 * BSSID was cached (in seconds). Add this with
2744 * time gap between system boot up to WiFi turn ON
2745 * to derive the time since boot when the
2746 * BSSID was cached.
2747 */
2748 pSirWifiScanResult->ts += pHddCtx->wifi_turn_on_time_since_boot;
2749 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2750 "Ssid (%s)"
2751 "Bssid: %pM "
2752 "Channel (%u)"
2753 "Rssi (%d)"
2754 "RTT (%u)"
2755 "RTT_SD (%u)"
2756 "Beacon Period %u"
2757 "Capability 0x%x "
2758 "Ie length %d",
2759 i,
2760 pSirWifiScanResult->ts,
2761 pSirWifiScanResult->ssid,
2762 pSirWifiScanResult->bssid,
2763 pSirWifiScanResult->channel,
2764 pSirWifiScanResult->rssi,
2765 pSirWifiScanResult->rtt,
2766 pSirWifiScanResult->rtt_sd,
2767 pSirWifiScanResult->beaconPeriod,
2768 pSirWifiScanResult->capability,
2769 ieLength);
2770
2771 ap = nla_nest_start(skb, j + 1);
2772 if (!ap)
2773 {
2774 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2775 goto fail;
2776 }
2777
2778 if (nla_put_u64(skb,
2779 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2780 pSirWifiScanResult->ts) )
2781 {
2782 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2783 goto fail;
2784 }
2785 if (nla_put(skb,
2786 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2787 sizeof(pSirWifiScanResult->ssid),
2788 pSirWifiScanResult->ssid) )
2789 {
2790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2791 goto fail;
2792 }
2793 if (nla_put(skb,
2794 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2795 sizeof(pSirWifiScanResult->bssid),
2796 pSirWifiScanResult->bssid) )
2797 {
2798 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2799 goto fail;
2800 }
2801 if (nla_put_u32(skb,
2802 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2803 pSirWifiScanResult->channel) )
2804 {
2805 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2806 goto fail;
2807 }
2808 if (nla_put_s32(skb,
2809 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2810 pSirWifiScanResult->rssi) )
2811 {
2812 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2813 goto fail;
2814 }
2815 if (nla_put_u32(skb,
2816 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2817 pSirWifiScanResult->rtt) )
2818 {
2819 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2820 goto fail;
2821 }
2822 if (nla_put_u32(skb,
2823 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2824 pSirWifiScanResult->rtt_sd))
2825 {
2826 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2827 goto fail;
2828 }
2829 if (nla_put_u32(skb,
2830 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2831 pSirWifiScanResult->beaconPeriod))
2832 {
2833 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2834 goto fail;
2835 }
2836 if (nla_put_u32(skb,
2837 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2838 pSirWifiScanResult->capability))
2839 {
2840 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2841 goto fail;
2842 }
2843 if (nla_put_u32(skb,
2844 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2845 ieLength))
2846 {
2847 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2848 goto fail;
2849 }
2850
2851 if (ieLength)
2852 if (nla_put(skb,
2853 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2854 ieLength, ie)) {
2855 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2856 goto fail;
2857 }
2858
2859 nla_nest_end(skb, ap);
2860 }
2861 nla_nest_end(skb, aps);
2862 nla_nest_end(skb, nla_result);
2863 }
2864
2865 nla_nest_end(skb, nla_results);
2866
2867 cfg80211_vendor_cmd_reply(skb);
2868
2869 } while (totalResults > 0);
2870 }
2871
2872 if (!pData->moreData) {
2873 spin_lock(&hdd_context_lock);
2874 context->response_status = 0;
2875 complete(&context->response_event);
2876 spin_unlock(&hdd_context_lock);
2877 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302878
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302879 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302880 return;
2881fail:
2882 kfree_skb(skb);
2883 return;
2884}
2885
2886static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2887 void *pMsg)
2888{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302889 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302890 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2891 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302892 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302893
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302894 ENTER();
2895
2896 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302897 hddLog(LOGE,
2898 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302899 return;
2900 }
2901 if (!pMsg)
2902 {
2903 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302904 return;
2905 }
2906
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302907 if (pData->bss_found)
2908 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2909 else
2910 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2911
Dino Mycle6fb96c12014-06-10 11:52:40 +05302912 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302913#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2914 NULL,
2915#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302916 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302917 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302918
2919 if (!skb) {
2920 hddLog(VOS_TRACE_LEVEL_ERROR,
2921 FL("cfg80211_vendor_event_alloc failed"));
2922 return;
2923 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302924
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302925 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2926 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2927 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2928 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2929
2930 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302931 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2932 "Ssid (%s) "
2933 "Bssid (" MAC_ADDRESS_STR ") "
2934 "Channel (%u) "
2935 "Rssi (%d) "
2936 "RTT (%u) "
2937 "RTT_SD (%u) ",
2938 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302939 pData->bssHotlist[i].ts,
2940 pData->bssHotlist[i].ssid,
2941 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2942 pData->bssHotlist[i].channel,
2943 pData->bssHotlist[i].rssi,
2944 pData->bssHotlist[i].rtt,
2945 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302946 }
2947
2948 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2949 pData->requestId) ||
2950 nla_put_u32(skb,
2951 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302952 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302953 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2954 goto fail;
2955 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302956 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302957 struct nlattr *aps;
2958
2959 aps = nla_nest_start(skb,
2960 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2961 if (!aps)
2962 goto fail;
2963
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302964 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302965 struct nlattr *ap;
2966
2967 ap = nla_nest_start(skb, i + 1);
2968 if (!ap)
2969 goto fail;
2970
2971 if (nla_put_u64(skb,
2972 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302973 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302974 nla_put(skb,
2975 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302976 sizeof(pData->bssHotlist[i].ssid),
2977 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302978 nla_put(skb,
2979 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302980 sizeof(pData->bssHotlist[i].bssid),
2981 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302982 nla_put_u32(skb,
2983 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302984 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302985 nla_put_s32(skb,
2986 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302987 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302988 nla_put_u32(skb,
2989 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302990 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302991 nla_put_u32(skb,
2992 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302993 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302994 goto fail;
2995
2996 nla_nest_end(skb, ap);
2997 }
2998 nla_nest_end(skb, aps);
2999
3000 if (nla_put_u8(skb,
3001 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3002 pData->moreData))
3003 goto fail;
3004 }
3005
3006 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303007 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303008 return;
3009
3010fail:
3011 kfree_skb(skb);
3012 return;
3013
3014}
Dino Mycle6fb96c12014-06-10 11:52:40 +05303015
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303016/**
3017 * wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind() -
3018 * Handle an SSID hotlist match event
3019 * @ctx: HDD context registered with SME
3020 * @event: The SSID hotlist match event
3021 *
3022 * This function will take an SSID match event that was generated by
3023 * firmware and will convert it into a cfg80211 vendor event which is
3024 * sent to userspace.
3025 *
3026 * Return: none
3027 */
3028static void
3029wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
3030 void *pMsg)
3031{
3032 hdd_context_t *hdd_ctx = ctx;
3033 struct sk_buff *skb;
3034 tANI_U32 i, index;
3035 tpSirEXTScanSsidHotlistMatch pData = (tpSirEXTScanSsidHotlistMatch) pMsg;
3036
3037 ENTER();
3038
3039 if (wlan_hdd_validate_context(hdd_ctx)) {
3040 hddLog(LOGE,
3041 FL("HDD context is not valid or response"));
3042 return;
3043 }
3044 if (!pMsg)
3045 {
3046 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3047 return;
3048 }
3049
3050 if (pData->ssid_found) {
3051 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX;
3052 hddLog(LOG1, "SSID hotlist found");
3053 } else {
3054 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX;
3055 hddLog(LOG1, "SSID hotlist lost");
3056 }
3057
3058 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
3059#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3060 NULL,
3061#endif
3062 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3063 index, GFP_KERNEL);
3064
3065 if (!skb) {
3066 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
3067 return;
3068 }
3069 hddLog(LOG1, "Req Id %u, Num of SSIDs %u, More Data (%u)",
3070 pData->requestId, pData->numHotlistSsid, pData->moreData);
3071
3072 for (i = 0; i < pData->numHotlistSsid; i++) {
3073 hddLog(LOG1, "[i=%d] Timestamp %llu "
3074 "Ssid: %s "
3075 "Bssid (" MAC_ADDRESS_STR ") "
3076 "Channel %u "
3077 "Rssi %d "
3078 "RTT %u "
3079 "RTT_SD %u",
3080 i,
3081 pData->ssidHotlist[i].ts,
3082 pData->ssidHotlist[i].ssid,
3083 MAC_ADDR_ARRAY(pData->ssidHotlist[i].bssid),
3084 pData->ssidHotlist[i].channel,
3085 pData->ssidHotlist[i].rssi,
3086 pData->ssidHotlist[i].rtt,
3087 pData->ssidHotlist[i].rtt_sd);
3088 }
3089
3090 if (nla_put_u32(skb,
3091 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3092 pData->requestId) ||
3093 nla_put_u32(skb,
3094 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3095 pData->numHotlistSsid)) {
3096 hddLog(LOGE, FL("put fail"));
3097 goto fail;
3098 }
3099
3100 if (pData->numHotlistSsid) {
3101 struct nlattr *aps;
3102 aps = nla_nest_start(skb,
3103 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3104 if (!aps) {
3105 hddLog(LOGE, FL("nest fail"));
3106 goto fail;
3107 }
3108
3109 for (i = 0; i < pData->numHotlistSsid; i++) {
3110 struct nlattr *ap;
3111
3112 ap = nla_nest_start(skb, i);
3113 if (!ap) {
3114 hddLog(LOGE, FL("nest fail"));
3115 goto fail;
3116 }
3117
3118 if (nla_put_u64(skb,
3119 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3120 pData->ssidHotlist[i].ts) ||
3121 nla_put(skb,
3122 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3123 sizeof(pData->ssidHotlist[i].ssid),
3124 pData->ssidHotlist[i].ssid) ||
3125 nla_put(skb,
3126 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3127 sizeof(pData->ssidHotlist[i].bssid),
3128 pData->ssidHotlist[i].bssid) ||
3129 nla_put_u32(skb,
3130 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3131 pData->ssidHotlist[i].channel) ||
3132 nla_put_s32(skb,
3133 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3134 pData->ssidHotlist[i].rssi) ||
3135 nla_put_u32(skb,
3136 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3137 pData->ssidHotlist[i].rtt) ||
3138 nla_put_u32(skb,
3139 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3140 pData->ssidHotlist[i].rtt_sd)) {
3141 hddLog(LOGE, FL("put fail"));
3142 goto fail;
3143 }
3144 nla_nest_end(skb, ap);
3145 }
3146 nla_nest_end(skb, aps);
3147
3148 if (nla_put_u8(skb,
3149 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3150 pData->moreData)) {
3151 hddLog(LOGE, FL("put fail"));
3152 goto fail;
3153 }
3154 }
3155
3156 cfg80211_vendor_event(skb, GFP_KERNEL);
3157 return;
3158
3159fail:
3160 kfree_skb(skb);
3161 return;
3162
3163}
3164
3165
Dino Mycle6fb96c12014-06-10 11:52:40 +05303166static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3167 void *pMsg)
3168{
3169 struct sk_buff *skb;
3170 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3171 tpSirWifiFullScanResultEvent pData =
3172 (tpSirWifiFullScanResultEvent) (pMsg);
3173
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303174 ENTER();
3175
3176 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303177 hddLog(LOGE,
3178 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303179 return;
3180 }
3181 if (!pMsg)
3182 {
3183 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303184 return;
3185 }
3186
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303187 /*
3188 * If the full scan result including IE data exceeds NL 4K size
3189 * limitation, drop that beacon/probe rsp frame.
3190 */
3191 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3192 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3193 return;
3194 }
3195
Dino Mycle6fb96c12014-06-10 11:52:40 +05303196 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303197#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3198 NULL,
3199#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303200 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3201 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3202 GFP_KERNEL);
3203
3204 if (!skb) {
3205 hddLog(VOS_TRACE_LEVEL_ERROR,
3206 FL("cfg80211_vendor_event_alloc failed"));
3207 return;
3208 }
3209
Dino Mycle6fb96c12014-06-10 11:52:40 +05303210 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3211 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3212 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3213 "Ssid (%s)"
3214 "Bssid (" MAC_ADDRESS_STR ")"
3215 "Channel (%u)"
3216 "Rssi (%d)"
3217 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303218 "RTT_SD (%u)"
3219 "Bcn Period %d"
3220 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303221 pData->ap.ts,
3222 pData->ap.ssid,
3223 MAC_ADDR_ARRAY(pData->ap.bssid),
3224 pData->ap.channel,
3225 pData->ap.rssi,
3226 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303227 pData->ap.rtt_sd,
3228 pData->ap.beaconPeriod,
3229 pData->ap.capability);
3230
Dino Mycle6fb96c12014-06-10 11:52:40 +05303231 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3232 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3233 pData->requestId) ||
3234 nla_put_u64(skb,
3235 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3236 pData->ap.ts) ||
3237 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3238 sizeof(pData->ap.ssid),
3239 pData->ap.ssid) ||
3240 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3241 WNI_CFG_BSSID_LEN,
3242 pData->ap.bssid) ||
3243 nla_put_u32(skb,
3244 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3245 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303246 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303247 pData->ap.rssi) ||
3248 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3249 pData->ap.rtt) ||
3250 nla_put_u32(skb,
3251 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3252 pData->ap.rtt_sd) ||
3253 nla_put_u16(skb,
3254 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3255 pData->ap.beaconPeriod) ||
3256 nla_put_u16(skb,
3257 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3258 pData->ap.capability) ||
3259 nla_put_u32(skb,
3260 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303261 pData->ieLength) ||
3262 nla_put_u8(skb,
3263 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3264 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303265 {
3266 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3267 goto nla_put_failure;
3268 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303269
3270 if (pData->ieLength) {
3271 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3272 pData->ieLength,
3273 pData->ie))
3274 {
3275 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3276 goto nla_put_failure;
3277 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303278 }
3279
3280 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303281 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303282 return;
3283
3284nla_put_failure:
3285 kfree_skb(skb);
3286 return;
3287}
3288
3289static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3290 void *pMsg)
3291{
3292 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3293 struct sk_buff *skb = NULL;
3294 tpSirEXTScanResultsAvailableIndParams pData =
3295 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3296
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303297 ENTER();
3298
3299 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303300 hddLog(LOGE,
3301 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303302 return;
3303 }
3304 if (!pMsg)
3305 {
3306 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303307 return;
3308 }
3309
3310 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303311#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3312 NULL,
3313#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303314 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3315 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3316 GFP_KERNEL);
3317
3318 if (!skb) {
3319 hddLog(VOS_TRACE_LEVEL_ERROR,
3320 FL("cfg80211_vendor_event_alloc failed"));
3321 return;
3322 }
3323
Dino Mycle6fb96c12014-06-10 11:52:40 +05303324 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3325 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3326 pData->numResultsAvailable);
3327 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3328 pData->requestId) ||
3329 nla_put_u32(skb,
3330 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3331 pData->numResultsAvailable)) {
3332 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3333 goto nla_put_failure;
3334 }
3335
3336 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303337 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303338 return;
3339
3340nla_put_failure:
3341 kfree_skb(skb);
3342 return;
3343}
3344
3345static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3346{
3347 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3348 struct sk_buff *skb = NULL;
3349 tpSirEXTScanProgressIndParams pData =
3350 (tpSirEXTScanProgressIndParams) pMsg;
3351
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303352 ENTER();
3353
3354 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303355 hddLog(LOGE,
3356 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303357 return;
3358 }
3359 if (!pMsg)
3360 {
3361 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303362 return;
3363 }
3364
3365 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303366#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3367 NULL,
3368#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303369 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3370 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3371 GFP_KERNEL);
3372
3373 if (!skb) {
3374 hddLog(VOS_TRACE_LEVEL_ERROR,
3375 FL("cfg80211_vendor_event_alloc failed"));
3376 return;
3377 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303378 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303379 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3380 pData->extScanEventType);
3381 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3382 pData->status);
3383
3384 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3385 pData->extScanEventType) ||
3386 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303387 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3388 pData->requestId) ||
3389 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303390 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3391 pData->status)) {
3392 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3393 goto nla_put_failure;
3394 }
3395
3396 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303397 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303398 return;
3399
3400nla_put_failure:
3401 kfree_skb(skb);
3402 return;
3403}
3404
3405void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3406 void *pMsg)
3407{
3408 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3409
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303410 ENTER();
3411
Dino Mycle6fb96c12014-06-10 11:52:40 +05303412 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303413 return;
3414 }
3415
3416 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3417
3418
3419 switch(evType) {
3420 case SIR_HAL_EXTSCAN_START_RSP:
3421 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3422 break;
3423
3424 case SIR_HAL_EXTSCAN_STOP_RSP:
3425 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3426 break;
3427 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3428 /* There is no need to send this response to upper layer
3429 Just log the message */
3430 hddLog(VOS_TRACE_LEVEL_INFO,
3431 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3432 break;
3433 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3434 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3435 break;
3436
3437 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3438 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3439 break;
3440
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303441 case SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP:
3442 wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(ctx, pMsg);
3443 break;
3444
3445 case SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP:
3446 wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(ctx, pMsg);
3447 break;
3448
Dino Mycle6fb96c12014-06-10 11:52:40 +05303449 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303450 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303451 break;
3452 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3453 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3454 break;
3455 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3456 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3457 break;
3458 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3459 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3460 break;
3461 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3462 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3463 break;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303464 case SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND:
3465 wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(ctx, pMsg);
3466 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303467 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3468 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3469 break;
3470 default:
3471 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3472 break;
3473 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303474 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303475}
3476
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303477static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3478 struct wireless_dev *wdev,
3479 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303480{
Dino Myclee8843b32014-07-04 14:21:45 +05303481 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303482 struct net_device *dev = wdev->netdev;
3483 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3484 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3485 struct nlattr
3486 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3487 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303488 struct hdd_ext_scan_context *context;
3489 unsigned long rc;
3490 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303491
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303492 ENTER();
3493
Dino Mycle6fb96c12014-06-10 11:52:40 +05303494 status = wlan_hdd_validate_context(pHddCtx);
3495 if (0 != status)
3496 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303497 return -EINVAL;
3498 }
Dino Myclee8843b32014-07-04 14:21:45 +05303499 /* check the EXTScan Capability */
3500 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303501 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3502 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303503 {
3504 hddLog(VOS_TRACE_LEVEL_ERROR,
3505 FL("EXTScan not enabled/supported by Firmware"));
3506 return -EINVAL;
3507 }
3508
Dino Mycle6fb96c12014-06-10 11:52:40 +05303509 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3510 data, dataLen,
3511 wlan_hdd_extscan_config_policy)) {
3512 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3513 return -EINVAL;
3514 }
3515
3516 /* Parse and fetch request Id */
3517 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3518 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3519 return -EINVAL;
3520 }
3521
Dino Myclee8843b32014-07-04 14:21:45 +05303522 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303523 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303524 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303525
Dino Myclee8843b32014-07-04 14:21:45 +05303526 reqMsg.sessionId = pAdapter->sessionId;
3527 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303528
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303529 vos_spin_lock_acquire(&hdd_context_lock);
3530 context = &pHddCtx->ext_scan_context;
3531 context->request_id = reqMsg.requestId;
3532 INIT_COMPLETION(context->response_event);
3533 vos_spin_lock_release(&hdd_context_lock);
3534
Dino Myclee8843b32014-07-04 14:21:45 +05303535 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303536 if (!HAL_STATUS_SUCCESS(status)) {
3537 hddLog(VOS_TRACE_LEVEL_ERROR,
3538 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303539 return -EINVAL;
3540 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303541
3542 rc = wait_for_completion_timeout(&context->response_event,
3543 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3544 if (!rc) {
3545 hddLog(LOGE, FL("Target response timed out"));
3546 return -ETIMEDOUT;
3547 }
3548
3549 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3550 if (ret)
3551 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3552
3553 return ret;
3554
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303555 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303556 return 0;
3557}
3558
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303559static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3560 struct wireless_dev *wdev,
3561 const void *data, int dataLen)
3562{
3563 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303564
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303565 vos_ssr_protect(__func__);
3566 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3567 vos_ssr_unprotect(__func__);
3568
3569 return ret;
3570}
3571
3572static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3573 struct wireless_dev *wdev,
3574 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303575{
Dino Myclee8843b32014-07-04 14:21:45 +05303576 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303577 struct net_device *dev = wdev->netdev;
3578 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3579 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3580 struct nlattr
3581 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3582 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303583 struct hdd_ext_scan_context *context;
3584 unsigned long rc;
3585 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303586
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303587 ENTER();
3588
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303589 if (VOS_FTM_MODE == hdd_get_conparam()) {
3590 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3591 return -EINVAL;
3592 }
3593
Dino Mycle6fb96c12014-06-10 11:52:40 +05303594 status = wlan_hdd_validate_context(pHddCtx);
3595 if (0 != status)
3596 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303597 return -EINVAL;
3598 }
Dino Myclee8843b32014-07-04 14:21:45 +05303599 /* check the EXTScan Capability */
3600 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303601 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3602 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303603 {
3604 hddLog(VOS_TRACE_LEVEL_ERROR,
3605 FL("EXTScan not enabled/supported by Firmware"));
3606 return -EINVAL;
3607 }
3608
Dino Mycle6fb96c12014-06-10 11:52:40 +05303609 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3610 data, dataLen,
3611 wlan_hdd_extscan_config_policy)) {
3612 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3613 return -EINVAL;
3614 }
3615 /* Parse and fetch request Id */
3616 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3618 return -EINVAL;
3619 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303620
Dino Myclee8843b32014-07-04 14:21:45 +05303621 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303622 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3623
Dino Myclee8843b32014-07-04 14:21:45 +05303624 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303625
Dino Myclee8843b32014-07-04 14:21:45 +05303626 reqMsg.sessionId = pAdapter->sessionId;
3627 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303628
3629 /* Parse and fetch flush parameter */
3630 if (!tb
3631 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3632 {
3633 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3634 goto failed;
3635 }
Dino Myclee8843b32014-07-04 14:21:45 +05303636 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303637 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3638
Dino Myclee8843b32014-07-04 14:21:45 +05303639 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303640
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303641 spin_lock(&hdd_context_lock);
3642 context = &pHddCtx->ext_scan_context;
3643 context->request_id = reqMsg.requestId;
3644 context->ignore_cached_results = false;
3645 INIT_COMPLETION(context->response_event);
3646 spin_unlock(&hdd_context_lock);
3647
Dino Myclee8843b32014-07-04 14:21:45 +05303648 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303649 if (!HAL_STATUS_SUCCESS(status)) {
3650 hddLog(VOS_TRACE_LEVEL_ERROR,
3651 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303652 return -EINVAL;
3653 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303654
3655 rc = wait_for_completion_timeout(&context->response_event,
3656 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3657 if (!rc) {
3658 hddLog(LOGE, FL("Target response timed out"));
3659 retval = -ETIMEDOUT;
3660 spin_lock(&hdd_context_lock);
3661 context->ignore_cached_results = true;
3662 spin_unlock(&hdd_context_lock);
3663 } else {
3664 spin_lock(&hdd_context_lock);
3665 retval = context->response_status;
3666 spin_unlock(&hdd_context_lock);
3667 }
3668
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303669 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303670 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303671
3672failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303673 return -EINVAL;
3674}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303675static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3676 struct wireless_dev *wdev,
3677 const void *data, int dataLen)
3678{
3679 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303680
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303681 vos_ssr_protect(__func__);
3682 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3683 vos_ssr_unprotect(__func__);
3684
3685 return ret;
3686}
3687
3688static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303689 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303690 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303691{
3692 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3693 struct net_device *dev = wdev->netdev;
3694 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3695 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3696 struct nlattr
3697 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3698 struct nlattr
3699 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3700 struct nlattr *apTh;
3701 eHalStatus status;
3702 tANI_U8 i = 0;
3703 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303704 struct hdd_ext_scan_context *context;
3705 tANI_U32 request_id;
3706 unsigned long rc;
3707 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303708
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303709 ENTER();
3710
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303711 if (VOS_FTM_MODE == hdd_get_conparam()) {
3712 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3713 return -EINVAL;
3714 }
3715
Dino Mycle6fb96c12014-06-10 11:52:40 +05303716 status = wlan_hdd_validate_context(pHddCtx);
3717 if (0 != status)
3718 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303719 return -EINVAL;
3720 }
Dino Myclee8843b32014-07-04 14:21:45 +05303721 /* check the EXTScan Capability */
3722 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303723 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3724 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303725 {
3726 hddLog(VOS_TRACE_LEVEL_ERROR,
3727 FL("EXTScan not enabled/supported by Firmware"));
3728 return -EINVAL;
3729 }
3730
Dino Mycle6fb96c12014-06-10 11:52:40 +05303731 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3732 data, dataLen,
3733 wlan_hdd_extscan_config_policy)) {
3734 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3735 return -EINVAL;
3736 }
3737
3738 /* Parse and fetch request Id */
3739 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3740 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3741 return -EINVAL;
3742 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303743 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3744 vos_mem_malloc(sizeof(*pReqMsg));
3745 if (!pReqMsg) {
3746 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3747 return -ENOMEM;
3748 }
3749
Dino Myclee8843b32014-07-04 14:21:45 +05303750
Dino Mycle6fb96c12014-06-10 11:52:40 +05303751 pReqMsg->requestId = nla_get_u32(
3752 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3753 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3754
3755 /* Parse and fetch number of APs */
3756 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3757 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3758 goto fail;
3759 }
3760
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303761 /* Parse and fetch lost ap sample size */
3762 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3763 hddLog(LOGE, FL("attr lost ap sample size failed"));
3764 goto fail;
3765 }
3766
3767 pReqMsg->lostBssidSampleSize = nla_get_u32(
3768 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3769 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3770
Dino Mycle6fb96c12014-06-10 11:52:40 +05303771 pReqMsg->sessionId = pAdapter->sessionId;
3772 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3773
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303774 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303775 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303776 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303777
3778 nla_for_each_nested(apTh,
3779 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3780 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3781 nla_data(apTh), nla_len(apTh),
3782 NULL)) {
3783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3784 goto fail;
3785 }
3786
3787 /* Parse and fetch MAC address */
3788 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3789 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3790 goto fail;
3791 }
3792 memcpy(pReqMsg->ap[i].bssid, nla_data(
3793 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3794 sizeof(tSirMacAddr));
3795 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3796
3797 /* Parse and fetch low RSSI */
3798 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3799 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3800 goto fail;
3801 }
3802 pReqMsg->ap[i].low = nla_get_s32(
3803 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3804 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3805
3806 /* Parse and fetch high RSSI */
3807 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3808 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3809 goto fail;
3810 }
3811 pReqMsg->ap[i].high = nla_get_s32(
3812 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3813 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3814 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303815 i++;
3816 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303817
3818 context = &pHddCtx->ext_scan_context;
3819 spin_lock(&hdd_context_lock);
3820 INIT_COMPLETION(context->response_event);
3821 context->request_id = request_id = pReqMsg->requestId;
3822 spin_unlock(&hdd_context_lock);
3823
Dino Mycle6fb96c12014-06-10 11:52:40 +05303824 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3825 if (!HAL_STATUS_SUCCESS(status)) {
3826 hddLog(VOS_TRACE_LEVEL_ERROR,
3827 FL("sme_SetBssHotlist failed(err=%d)"), status);
3828 vos_mem_free(pReqMsg);
3829 return -EINVAL;
3830 }
3831
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303832 /* request was sent -- wait for the response */
3833 rc = wait_for_completion_timeout(&context->response_event,
3834 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3835
3836 if (!rc) {
3837 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3838 retval = -ETIMEDOUT;
3839 } else {
3840 spin_lock(&hdd_context_lock);
3841 if (context->request_id == request_id)
3842 retval = context->response_status;
3843 else
3844 retval = -EINVAL;
3845 spin_unlock(&hdd_context_lock);
3846 }
3847
Dino Myclee8843b32014-07-04 14:21:45 +05303848 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303849 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303850 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303851
3852fail:
3853 vos_mem_free(pReqMsg);
3854 return -EINVAL;
3855}
3856
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303857static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3858 struct wireless_dev *wdev,
3859 const void *data, int dataLen)
3860{
3861 int ret = 0;
3862
3863 vos_ssr_protect(__func__);
3864 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3865 dataLen);
3866 vos_ssr_unprotect(__func__);
3867
3868 return ret;
3869}
3870
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303871/*
3872 * define short names for the global vendor params
3873 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
3874 */
3875#define PARAM_MAX \
3876QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
3877#define PARAM_REQUEST_ID \
3878QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3879#define PARAMS_LOST_SSID_SAMPLE_SIZE \
3880QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE
3881#define PARAMS_NUM_SSID \
3882QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID
3883#define THRESHOLD_PARAM \
3884QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM
3885#define PARAM_SSID \
3886QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID
3887#define PARAM_BAND \
3888QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND
3889#define PARAM_RSSI_LOW \
3890QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW
3891#define PARAM_RSSI_HIGH \
3892QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH
3893
3894/**
3895 * __wlan_hdd_cfg80211_extscan_set_ssid_hotlist() - set ssid hot list
3896 * @wiphy: Pointer to wireless phy
3897 * @wdev: Pointer to wireless device
3898 * @data: Pointer to data
3899 * @data_len: Data length
3900 *
3901 * Return: 0 on success, negative errno on failure
3902 */
3903static int
3904__wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
3905 struct wireless_dev *wdev,
3906 const void *data,
3907 int data_len)
3908{
3909 tSirEXTScanSetSsidHotListReqParams *request;
3910 struct net_device *dev = wdev->netdev;
3911 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3912 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
3913 struct nlattr *tb[PARAM_MAX + 1];
3914 struct nlattr *tb2[PARAM_MAX + 1];
3915 struct nlattr *ssids;
3916 struct hdd_ext_scan_context *context;
3917 uint32_t request_id;
3918 char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1] = {'\0'};
3919 int ssid_len;
3920 eHalStatus status;
3921 int i, rem, retval;
3922 unsigned long rc;
3923
3924 ENTER();
3925
3926 if (VOS_FTM_MODE == hdd_get_conparam()) {
3927 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3928 return -EINVAL;
3929 }
3930
3931 retval = wlan_hdd_validate_context(hdd_ctx);
3932 if (0 != retval) {
3933 hddLog(LOGE, FL("HDD context is not valid"));
3934 return -EINVAL;
3935 }
3936
3937 /* check the EXTScan Capability */
3938 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303939 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3940 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303941 {
3942 hddLog(VOS_TRACE_LEVEL_ERROR,
3943 FL("EXTScan not enabled/supported by Firmware"));
3944 return -EINVAL;
3945 }
3946
3947 if (nla_parse(tb, PARAM_MAX,
3948 data, data_len,
3949 wlan_hdd_extscan_config_policy)) {
3950 hddLog(LOGE, FL("Invalid ATTR"));
3951 return -EINVAL;
3952 }
3953
3954 request = vos_mem_malloc(sizeof(*request));
3955 if (!request) {
3956 hddLog(LOGE, FL("vos_mem_malloc failed"));
3957 return -ENOMEM;
3958 }
3959
3960 /* Parse and fetch request Id */
3961 if (!tb[PARAM_REQUEST_ID]) {
3962 hddLog(LOGE, FL("attr request id failed"));
3963 goto fail;
3964 }
3965
3966 request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
3967 hddLog(LOG1, FL("Request Id %d"), request->request_id);
3968
3969 /* Parse and fetch lost SSID sample size */
3970 if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
3971 hddLog(LOGE, FL("attr number of Ssid failed"));
3972 goto fail;
3973 }
3974 request->lost_ssid_sample_size =
3975 nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
3976 hddLog(LOG1, FL("Lost SSID Sample Size %d"),
3977 request->lost_ssid_sample_size);
3978
3979 /* Parse and fetch number of hotlist SSID */
3980 if (!tb[PARAMS_NUM_SSID]) {
3981 hddLog(LOGE, FL("attr number of Ssid failed"));
3982 goto fail;
3983 }
3984 request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
3985 hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
3986
3987 request->session_id = adapter->sessionId;
3988 hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
3989
3990 i = 0;
3991 nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
3992 if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
3993 hddLog(LOGE,
3994 FL("Too Many SSIDs, %d exceeds %d"),
3995 i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
3996 break;
3997 }
3998 if (nla_parse(tb2, PARAM_MAX,
3999 nla_data(ssids), nla_len(ssids),
4000 wlan_hdd_extscan_config_policy)) {
4001 hddLog(LOGE, FL("nla_parse failed"));
4002 goto fail;
4003 }
4004
4005 /* Parse and fetch SSID */
4006 if (!tb2[PARAM_SSID]) {
4007 hddLog(LOGE, FL("attr ssid failed"));
4008 goto fail;
4009 }
4010 nla_memcpy(ssid_string,
4011 tb2[PARAM_SSID],
4012 sizeof(ssid_string));
4013 hddLog(LOG1, FL("SSID %s"),
4014 ssid_string);
4015 ssid_len = strlen(ssid_string);
4016 memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
4017 request->ssid[i].ssid.length = ssid_len;
4018 request->ssid[i].ssid.ssId[ssid_len] = '\0';
4019 hddLog(LOG1, FL("After copying SSID %s"),
4020 request->ssid[i].ssid.ssId);
4021 hddLog(LOG1, FL("After copying length: %d"),
4022 ssid_len);
4023
4024 /* Parse and fetch low RSSI */
4025 if (!tb2[PARAM_BAND]) {
4026 hddLog(LOGE, FL("attr band failed"));
4027 goto fail;
4028 }
4029 request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
4030 hddLog(LOG1, FL("band %d"), request->ssid[i].band);
4031
4032 /* Parse and fetch low RSSI */
4033 if (!tb2[PARAM_RSSI_LOW]) {
4034 hddLog(LOGE, FL("attr low RSSI failed"));
4035 goto fail;
4036 }
4037 request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
4038 hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
4039
4040 /* Parse and fetch high RSSI */
4041 if (!tb2[PARAM_RSSI_HIGH]) {
4042 hddLog(LOGE, FL("attr high RSSI failed"));
4043 goto fail;
4044 }
4045 request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
4046 hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
4047 i++;
4048 }
4049
4050 context = &hdd_ctx->ext_scan_context;
4051 spin_lock(&hdd_context_lock);
4052 INIT_COMPLETION(context->response_event);
4053 context->request_id = request_id = request->request_id;
4054 spin_unlock(&hdd_context_lock);
4055
4056 status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
4057 if (!HAL_STATUS_SUCCESS(status)) {
4058 hddLog(LOGE,
4059 FL("sme_set_ssid_hotlist failed(err=%d)"), status);
4060 goto fail;
4061 }
4062
4063 vos_mem_free(request);
4064
4065 /* request was sent -- wait for the response */
4066 rc = wait_for_completion_timeout(&context->response_event,
4067 msecs_to_jiffies
4068 (WLAN_WAIT_TIME_EXTSCAN));
4069 if (!rc) {
4070 hddLog(LOGE, FL("sme_set_ssid_hotlist timed out"));
4071 retval = -ETIMEDOUT;
4072 } else {
4073 spin_lock(&hdd_context_lock);
4074 if (context->request_id == request_id)
4075 retval = context->response_status;
4076 else
4077 retval = -EINVAL;
4078 spin_unlock(&hdd_context_lock);
4079 }
4080
4081 return retval;
4082
4083fail:
4084 vos_mem_free(request);
4085 return -EINVAL;
4086}
4087
4088/*
4089 * done with short names for the global vendor params
4090 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4091 */
4092#undef PARAM_MAX
4093#undef PARAM_REQUEST_ID
4094#undef PARAMS_NUM_SSID
4095#undef THRESHOLD_PARAM
4096#undef PARAM_SSID
4097#undef PARAM_BAND
4098#undef PARAM_RSSI_LOW
4099#undef PARAM_RSSI_HIGH
4100
4101static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4102 struct wireless_dev *wdev,
4103 const void *data, int dataLen)
4104{
4105 int ret = 0;
4106
4107 vos_ssr_protect(__func__);
4108 ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
4109 dataLen);
4110 vos_ssr_unprotect(__func__);
4111
4112 return ret;
4113}
4114
4115static int
4116__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4117 struct wireless_dev *wdev,
4118 const void *data,
4119 int data_len)
4120{
4121 tSirEXTScanResetSsidHotlistReqParams request;
4122 struct net_device *dev = wdev->netdev;
4123 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4124 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4125 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4126 struct hdd_ext_scan_context *context;
4127 uint32_t request_id;
4128 eHalStatus status;
4129 int retval;
4130 unsigned long rc;
4131
4132 ENTER();
4133
4134 if (VOS_FTM_MODE == hdd_get_conparam()) {
4135 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4136 return -EINVAL;
4137 }
4138
4139 retval = wlan_hdd_validate_context(hdd_ctx);
4140 if (0 != retval) {
4141 hddLog(LOGE, FL("HDD context is not valid"));
4142 return -EINVAL;
4143 }
4144
4145 /* check the EXTScan Capability */
4146 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304147 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4148 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304149 {
4150 hddLog(LOGE,
4151 FL("EXTScan not enabled/supported by Firmware"));
4152 return -EINVAL;
4153 }
4154
4155 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4156 data, data_len,
4157 wlan_hdd_extscan_config_policy)) {
4158 hddLog(LOGE, FL("Invalid ATTR"));
4159 return -EINVAL;
4160 }
4161
4162 /* Parse and fetch request Id */
4163 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4164 hddLog(LOGE, FL("attr request id failed"));
4165 return -EINVAL;
4166 }
4167
4168 request.requestId = nla_get_u32(
4169 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4170 request.sessionId = adapter->sessionId;
4171 hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
4172 request.sessionId);
4173
4174 context = &hdd_ctx->ext_scan_context;
4175 spin_lock(&hdd_context_lock);
4176 INIT_COMPLETION(context->response_event);
4177 context->request_id = request_id = request.requestId;
4178 spin_unlock(&hdd_context_lock);
4179
4180 status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
4181 if (!HAL_STATUS_SUCCESS(status)) {
4182 hddLog(LOGE,
4183 FL("sme_reset_ssid_hotlist failed(err=%d)"), status);
4184 return -EINVAL;
4185 }
4186
4187 /* request was sent -- wait for the response */
4188 rc = wait_for_completion_timeout(&context->response_event,
4189 msecs_to_jiffies
4190 (WLAN_WAIT_TIME_EXTSCAN));
4191 if (!rc) {
4192 hddLog(LOGE, FL("sme_reset_ssid_hotlist timed out"));
4193 retval = -ETIMEDOUT;
4194 } else {
4195 spin_lock(&hdd_context_lock);
4196 if (context->request_id == request_id)
4197 retval = context->response_status;
4198 else
4199 retval = -EINVAL;
4200 spin_unlock(&hdd_context_lock);
4201 }
4202
4203 return retval;
4204}
4205
4206static int
4207wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4208 struct wireless_dev *wdev,
4209 const void *data,
4210 int data_len)
4211{
4212 int ret;
4213
4214 vos_ssr_protect(__func__);
4215 ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
4216 data, data_len);
4217 vos_ssr_unprotect(__func__);
4218
4219 return ret;
4220}
4221
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304222static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304223 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304224 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304225{
4226 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4227 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4228 tANI_U8 numChannels = 0;
4229 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304230 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304231 tWifiBand wifiBand;
4232 eHalStatus status;
4233 struct sk_buff *replySkb;
4234 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304235 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304236
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304237 ENTER();
4238
Dino Mycle6fb96c12014-06-10 11:52:40 +05304239 status = wlan_hdd_validate_context(pHddCtx);
4240 if (0 != status)
4241 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304242 return -EINVAL;
4243 }
Dino Myclee8843b32014-07-04 14:21:45 +05304244
Dino Mycle6fb96c12014-06-10 11:52:40 +05304245 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4246 data, dataLen,
4247 wlan_hdd_extscan_config_policy)) {
4248 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4249 return -EINVAL;
4250 }
4251
4252 /* Parse and fetch request Id */
4253 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4254 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4255 return -EINVAL;
4256 }
4257 requestId = nla_get_u32(
4258 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4259 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4260
4261 /* Parse and fetch wifi band */
4262 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4263 {
4264 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4265 return -EINVAL;
4266 }
4267 wifiBand = nla_get_u32(
4268 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4269 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4270
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304271 /* Parse and fetch max channels */
4272 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4273 {
4274 hddLog(LOGE, FL("attr max channels failed"));
4275 return -EINVAL;
4276 }
4277 maxChannels = nla_get_u32(
4278 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4279 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4280
Dino Mycle6fb96c12014-06-10 11:52:40 +05304281 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
4282 wifiBand, ChannelList,
4283 &numChannels);
4284 if (eHAL_STATUS_SUCCESS != status) {
4285 hddLog(VOS_TRACE_LEVEL_ERROR,
4286 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4287 return -EINVAL;
4288 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304289
4290 numChannels = VOS_MIN(numChannels, maxChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304291 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304292
Dino Mycle6fb96c12014-06-10 11:52:40 +05304293 for (i = 0; i < numChannels; i++)
4294 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
4295
4296 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4297 sizeof(u32) * numChannels +
4298 NLMSG_HDRLEN);
4299
4300 if (!replySkb) {
4301 hddLog(VOS_TRACE_LEVEL_ERROR,
4302 FL("valid channels: buffer alloc fail"));
4303 return -EINVAL;
4304 }
4305 if (nla_put_u32(replySkb,
4306 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
4307 numChannels) ||
4308 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
4309 sizeof(u32) * numChannels, ChannelList)) {
4310
4311 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4312 kfree_skb(replySkb);
4313 return -EINVAL;
4314 }
4315
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304316 ret = cfg80211_vendor_cmd_reply(replySkb);
4317
4318 EXIT();
4319 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304320}
4321
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304322static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4323 struct wireless_dev *wdev,
4324 const void *data, int dataLen)
4325{
4326 int ret = 0;
4327
4328 vos_ssr_protect(__func__);
4329 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4330 dataLen);
4331 vos_ssr_unprotect(__func__);
4332
4333 return ret;
4334}
4335
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304336static int hdd_extscan_start_fill_bucket_channel_spec(
4337 hdd_context_t *pHddCtx,
4338 tpSirEXTScanStartReqParams pReqMsg,
4339 struct nlattr **tb)
4340{
4341 struct nlattr *bucket[
4342 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4343 struct nlattr *channel[
4344 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4345 struct nlattr *buckets;
4346 struct nlattr *channels;
4347 int rem1, rem2;
4348 eHalStatus status;
4349 tANI_U8 bktIndex, j, numChannels;
4350 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4351 tANI_U32 passive_max_chn_time, active_max_chn_time;
4352
4353 bktIndex = 0;
4354
4355 nla_for_each_nested(buckets,
4356 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4357 if (nla_parse(bucket,
4358 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4359 nla_data(buckets), nla_len(buckets), NULL)) {
4360 hddLog(LOGE, FL("nla_parse failed"));
4361 return -EINVAL;
4362 }
4363
4364 /* Parse and fetch bucket spec */
4365 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4366 hddLog(LOGE, FL("attr bucket index failed"));
4367 return -EINVAL;
4368 }
4369 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4370 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4371 hddLog(LOG1, FL("Bucket spec Index %d"),
4372 pReqMsg->buckets[bktIndex].bucket);
4373
4374 /* Parse and fetch wifi band */
4375 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4376 hddLog(LOGE, FL("attr wifi band failed"));
4377 return -EINVAL;
4378 }
4379 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4380 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4381 hddLog(LOG1, FL("Wifi band %d"),
4382 pReqMsg->buckets[bktIndex].band);
4383
4384 /* Parse and fetch period */
4385 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4386 hddLog(LOGE, FL("attr period failed"));
4387 return -EINVAL;
4388 }
4389 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4390 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4391 hddLog(LOG1, FL("period %d"),
4392 pReqMsg->buckets[bktIndex].period);
4393
4394 /* Parse and fetch report events */
4395 if (!bucket[
4396 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4397 hddLog(LOGE, FL("attr report events failed"));
4398 return -EINVAL;
4399 }
4400 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4401 bucket[
4402 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4403 hddLog(LOG1, FL("report events %d"),
4404 pReqMsg->buckets[bktIndex].reportEvents);
4405
4406 /* Parse and fetch max period */
4407 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4408 hddLog(LOGE, FL("attr max period failed"));
4409 return -EINVAL;
4410 }
4411 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4412 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4413 hddLog(LOG1, FL("max period %u"),
4414 pReqMsg->buckets[bktIndex].max_period);
4415
4416 /* Parse and fetch exponent */
4417 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4418 hddLog(LOGE, FL("attr exponent failed"));
4419 return -EINVAL;
4420 }
4421 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4422 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4423 hddLog(LOG1, FL("exponent %u"),
4424 pReqMsg->buckets[bktIndex].exponent);
4425
4426 /* Parse and fetch step count */
4427 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4428 hddLog(LOGE, FL("attr step count failed"));
4429 return -EINVAL;
4430 }
4431 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4432 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4433 hddLog(LOG1, FL("Step count %u"),
4434 pReqMsg->buckets[bktIndex].step_count);
4435
4436 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4437 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4438
4439 /* Framework shall pass the channel list if the input WiFi band is
4440 * WIFI_BAND_UNSPECIFIED.
4441 * If the input WiFi band is specified (any value other than
4442 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4443 */
4444 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4445 numChannels = 0;
4446 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4447 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4448 pReqMsg->buckets[bktIndex].band,
4449 chanList, &numChannels);
4450 if (!HAL_STATUS_SUCCESS(status)) {
4451 hddLog(LOGE,
4452 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4453 status);
4454 return -EINVAL;
4455 }
4456
4457 pReqMsg->buckets[bktIndex].numChannels =
4458 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4459 hddLog(LOG1, FL("Num channels %d"),
4460 pReqMsg->buckets[bktIndex].numChannels);
4461
4462 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4463 j++) {
4464 pReqMsg->buckets[bktIndex].channels[j].channel =
4465 chanList[j];
4466 pReqMsg->buckets[bktIndex].channels[j].
4467 chnlClass = 0;
4468 if (CSR_IS_CHANNEL_DFS(
4469 vos_freq_to_chan(chanList[j]))) {
4470 pReqMsg->buckets[bktIndex].channels[j].
4471 passive = 1;
4472 pReqMsg->buckets[bktIndex].channels[j].
4473 dwellTimeMs = passive_max_chn_time;
4474 } else {
4475 pReqMsg->buckets[bktIndex].channels[j].
4476 passive = 0;
4477 pReqMsg->buckets[bktIndex].channels[j].
4478 dwellTimeMs = active_max_chn_time;
4479 }
4480
4481 hddLog(LOG1,
4482 "Channel %u Passive %u Dwell time %u ms",
4483 pReqMsg->buckets[bktIndex].channels[j].channel,
4484 pReqMsg->buckets[bktIndex].channels[j].passive,
4485 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4486 }
4487
4488 bktIndex++;
4489 continue;
4490 }
4491
4492 /* Parse and fetch number of channels */
4493 if (!bucket[
4494 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4495 hddLog(LOGE, FL("attr num channels failed"));
4496 return -EINVAL;
4497 }
4498
4499 pReqMsg->buckets[bktIndex].numChannels =
4500 nla_get_u32(bucket[
4501 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4502 hddLog(LOG1, FL("num channels %d"),
4503 pReqMsg->buckets[bktIndex].numChannels);
4504
4505 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4506 hddLog(LOGE, FL("attr channel spec failed"));
4507 return -EINVAL;
4508 }
4509
4510 j = 0;
4511 nla_for_each_nested(channels,
4512 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4513 if (nla_parse(channel,
4514 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4515 nla_data(channels), nla_len(channels),
4516 wlan_hdd_extscan_config_policy)) {
4517 hddLog(LOGE, FL("nla_parse failed"));
4518 return -EINVAL;
4519 }
4520
4521 /* Parse and fetch channel */
4522 if (!channel[
4523 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4524 hddLog(LOGE, FL("attr channel failed"));
4525 return -EINVAL;
4526 }
4527 pReqMsg->buckets[bktIndex].channels[j].channel =
4528 nla_get_u32(channel[
4529 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4530 hddLog(LOG1, FL("channel %u"),
4531 pReqMsg->buckets[bktIndex].channels[j].channel);
4532
4533 /* Parse and fetch dwell time */
4534 if (!channel[
4535 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4536 hddLog(LOGE, FL("attr dwelltime failed"));
4537 return -EINVAL;
4538 }
4539 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4540 nla_get_u32(channel[
4541 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4542
4543 hddLog(LOG1, FL("Dwell time (%u ms)"),
4544 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4545
4546
4547 /* Parse and fetch channel spec passive */
4548 if (!channel[
4549 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4550 hddLog(LOGE,
4551 FL("attr channel spec passive failed"));
4552 return -EINVAL;
4553 }
4554 pReqMsg->buckets[bktIndex].channels[j].passive =
4555 nla_get_u8(channel[
4556 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4557 hddLog(LOG1, FL("Chnl spec passive %u"),
4558 pReqMsg->buckets[bktIndex].channels[j].passive);
4559
4560 j++;
4561 }
4562
4563 bktIndex++;
4564 }
4565
4566 return 0;
4567}
4568
4569
4570/*
4571 * define short names for the global vendor params
4572 * used by wlan_hdd_cfg80211_extscan_start()
4573 */
4574#define PARAM_MAX \
4575QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4576#define PARAM_REQUEST_ID \
4577QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4578#define PARAM_BASE_PERIOD \
4579QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4580#define PARAM_MAX_AP_PER_SCAN \
4581QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4582#define PARAM_RPT_THRHLD_PERCENT \
4583QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4584#define PARAM_RPT_THRHLD_NUM_SCANS \
4585QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4586#define PARAM_NUM_BUCKETS \
4587QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4588
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304589static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304590 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304591 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304592{
Dino Myclee8843b32014-07-04 14:21:45 +05304593 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304594 struct net_device *dev = wdev->netdev;
4595 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4596 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4597 struct nlattr *tb[PARAM_MAX + 1];
4598 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304599 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304600 tANI_U32 request_id;
4601 struct hdd_ext_scan_context *context;
4602 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304603
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304604 ENTER();
4605
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304606 if (VOS_FTM_MODE == hdd_get_conparam()) {
4607 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4608 return -EINVAL;
4609 }
4610
Dino Mycle6fb96c12014-06-10 11:52:40 +05304611 status = wlan_hdd_validate_context(pHddCtx);
4612 if (0 != status)
4613 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304614 return -EINVAL;
4615 }
Dino Myclee8843b32014-07-04 14:21:45 +05304616 /* check the EXTScan Capability */
4617 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304618 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4619 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304620 {
4621 hddLog(VOS_TRACE_LEVEL_ERROR,
4622 FL("EXTScan not enabled/supported by Firmware"));
4623 return -EINVAL;
4624 }
4625
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304626 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304627 data, dataLen,
4628 wlan_hdd_extscan_config_policy)) {
4629 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4630 return -EINVAL;
4631 }
4632
4633 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304634 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304635 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4636 return -EINVAL;
4637 }
4638
Dino Myclee8843b32014-07-04 14:21:45 +05304639 pReqMsg = (tpSirEXTScanStartReqParams)
4640 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304641 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304642 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4643 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304644 }
4645
4646 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304647 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304648 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4649
4650 pReqMsg->sessionId = pAdapter->sessionId;
4651 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4652
4653 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304654 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304655 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4656 goto fail;
4657 }
4658 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304659 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304660 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4661 pReqMsg->basePeriod);
4662
4663 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304664 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304665 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4666 goto fail;
4667 }
4668 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304669 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304670 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4671 pReqMsg->maxAPperScan);
4672
4673 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304674 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304675 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4676 goto fail;
4677 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304678 pReqMsg->reportThresholdPercent = nla_get_u8(
4679 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304680 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304681 pReqMsg->reportThresholdPercent);
4682
4683 /* Parse and fetch report threshold num scans */
4684 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4685 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4686 goto fail;
4687 }
4688 pReqMsg->reportThresholdNumScans = nla_get_u8(
4689 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4690 hddLog(LOG1, FL("Report Threshold num scans %d"),
4691 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304692
4693 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304694 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4696 goto fail;
4697 }
4698 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304699 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304700 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4701 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4702 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4703 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4704 }
4705 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4706 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304707
Dino Mycle6fb96c12014-06-10 11:52:40 +05304708 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4709 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4710 goto fail;
4711 }
4712
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304713 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304714
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304715 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4716 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304717
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304718 context = &pHddCtx->ext_scan_context;
4719 spin_lock(&hdd_context_lock);
4720 INIT_COMPLETION(context->response_event);
4721 context->request_id = request_id = pReqMsg->requestId;
4722 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304723
Dino Mycle6fb96c12014-06-10 11:52:40 +05304724 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4725 if (!HAL_STATUS_SUCCESS(status)) {
4726 hddLog(VOS_TRACE_LEVEL_ERROR,
4727 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304728 goto fail;
4729 }
4730
4731 /* request was sent -- wait for the response */
4732 rc = wait_for_completion_timeout(&context->response_event,
4733 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4734
4735 if (!rc) {
4736 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4737 retval = -ETIMEDOUT;
4738 } else {
4739 spin_lock(&hdd_context_lock);
4740 if (context->request_id == request_id)
4741 retval = context->response_status;
4742 else
4743 retval = -EINVAL;
4744 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304745 }
4746
Dino Myclee8843b32014-07-04 14:21:45 +05304747 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304748 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304749 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304750
4751fail:
4752 vos_mem_free(pReqMsg);
4753 return -EINVAL;
4754}
4755
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304756/*
4757 * done with short names for the global vendor params
4758 * used by wlan_hdd_cfg80211_extscan_start()
4759 */
4760#undef PARAM_MAX
4761#undef PARAM_REQUEST_ID
4762#undef PARAM_BASE_PERIOD
4763#undef PARAMS_MAX_AP_PER_SCAN
4764#undef PARAMS_RPT_THRHLD_PERCENT
4765#undef PARAMS_RPT_THRHLD_NUM_SCANS
4766#undef PARAMS_NUM_BUCKETS
4767
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304768static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4769 struct wireless_dev *wdev,
4770 const void *data, int dataLen)
4771{
4772 int ret = 0;
4773
4774 vos_ssr_protect(__func__);
4775 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4776 vos_ssr_unprotect(__func__);
4777
4778 return ret;
4779}
4780
4781static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304782 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304783 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304784{
Dino Myclee8843b32014-07-04 14:21:45 +05304785 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304786 struct net_device *dev = wdev->netdev;
4787 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4788 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4789 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4790 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304791 int retval;
4792 unsigned long rc;
4793 struct hdd_ext_scan_context *context;
4794 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304795
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304796 ENTER();
4797
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304798 if (VOS_FTM_MODE == hdd_get_conparam()) {
4799 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4800 return -EINVAL;
4801 }
4802
Dino Mycle6fb96c12014-06-10 11:52:40 +05304803 status = wlan_hdd_validate_context(pHddCtx);
4804 if (0 != status)
4805 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304806 return -EINVAL;
4807 }
Dino Myclee8843b32014-07-04 14:21:45 +05304808 /* check the EXTScan Capability */
4809 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304810 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4811 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304812 {
4813 hddLog(VOS_TRACE_LEVEL_ERROR,
4814 FL("EXTScan not enabled/supported by Firmware"));
4815 return -EINVAL;
4816 }
4817
Dino Mycle6fb96c12014-06-10 11:52:40 +05304818 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4819 data, dataLen,
4820 wlan_hdd_extscan_config_policy)) {
4821 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4822 return -EINVAL;
4823 }
4824
4825 /* Parse and fetch request Id */
4826 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4827 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4828 return -EINVAL;
4829 }
4830
Dino Myclee8843b32014-07-04 14:21:45 +05304831 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304832 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304833 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304834
Dino Myclee8843b32014-07-04 14:21:45 +05304835 reqMsg.sessionId = pAdapter->sessionId;
4836 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304837
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304838 context = &pHddCtx->ext_scan_context;
4839 spin_lock(&hdd_context_lock);
4840 INIT_COMPLETION(context->response_event);
4841 context->request_id = request_id = reqMsg.sessionId;
4842 spin_unlock(&hdd_context_lock);
4843
Dino Myclee8843b32014-07-04 14:21:45 +05304844 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304845 if (!HAL_STATUS_SUCCESS(status)) {
4846 hddLog(VOS_TRACE_LEVEL_ERROR,
4847 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304848 return -EINVAL;
4849 }
4850
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304851 /* request was sent -- wait for the response */
4852 rc = wait_for_completion_timeout(&context->response_event,
4853 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4854
4855 if (!rc) {
4856 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4857 retval = -ETIMEDOUT;
4858 } else {
4859 spin_lock(&hdd_context_lock);
4860 if (context->request_id == request_id)
4861 retval = context->response_status;
4862 else
4863 retval = -EINVAL;
4864 spin_unlock(&hdd_context_lock);
4865 }
4866
4867 return retval;
4868
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304869 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304870 return 0;
4871}
4872
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304873static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4874 struct wireless_dev *wdev,
4875 const void *data, int dataLen)
4876{
4877 int ret = 0;
4878
4879 vos_ssr_protect(__func__);
4880 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4881 vos_ssr_unprotect(__func__);
4882
4883 return ret;
4884}
4885
4886static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304887 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304888 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304889{
Dino Myclee8843b32014-07-04 14:21:45 +05304890 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304891 struct net_device *dev = wdev->netdev;
4892 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4893 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4894 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4895 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304896 struct hdd_ext_scan_context *context;
4897 tANI_U32 request_id;
4898 unsigned long rc;
4899 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304900
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304901 ENTER();
4902
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304903 if (VOS_FTM_MODE == hdd_get_conparam()) {
4904 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4905 return -EINVAL;
4906 }
4907
Dino Mycle6fb96c12014-06-10 11:52:40 +05304908 status = wlan_hdd_validate_context(pHddCtx);
4909 if (0 != status)
4910 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304911 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304912 return -EINVAL;
4913 }
Dino Myclee8843b32014-07-04 14:21:45 +05304914 /* check the EXTScan Capability */
4915 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304916 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4917 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304918 {
4919 hddLog(VOS_TRACE_LEVEL_ERROR,
4920 FL("EXTScan not enabled/supported by Firmware"));
4921 return -EINVAL;
4922 }
4923
Dino Mycle6fb96c12014-06-10 11:52:40 +05304924 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4925 data, dataLen,
4926 wlan_hdd_extscan_config_policy)) {
4927 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4928 return -EINVAL;
4929 }
4930
4931 /* Parse and fetch request Id */
4932 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4933 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4934 return -EINVAL;
4935 }
4936
Dino Myclee8843b32014-07-04 14:21:45 +05304937 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304938 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304939 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304940
Dino Myclee8843b32014-07-04 14:21:45 +05304941 reqMsg.sessionId = pAdapter->sessionId;
4942 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304943
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304944 context = &pHddCtx->ext_scan_context;
4945 spin_lock(&hdd_context_lock);
4946 INIT_COMPLETION(context->response_event);
4947 context->request_id = request_id = reqMsg.requestId;
4948 spin_unlock(&hdd_context_lock);
4949
Dino Myclee8843b32014-07-04 14:21:45 +05304950 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304951 if (!HAL_STATUS_SUCCESS(status)) {
4952 hddLog(VOS_TRACE_LEVEL_ERROR,
4953 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304954 return -EINVAL;
4955 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304956
4957 /* request was sent -- wait for the response */
4958 rc = wait_for_completion_timeout(&context->response_event,
4959 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4960 if (!rc) {
4961 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4962 retval = -ETIMEDOUT;
4963 } else {
4964 spin_lock(&hdd_context_lock);
4965 if (context->request_id == request_id)
4966 retval = context->response_status;
4967 else
4968 retval = -EINVAL;
4969 spin_unlock(&hdd_context_lock);
4970 }
4971
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304972 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304973 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304974}
4975
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304976static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4977 struct wireless_dev *wdev,
4978 const void *data, int dataLen)
4979{
4980 int ret = 0;
4981
4982 vos_ssr_protect(__func__);
4983 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4984 vos_ssr_unprotect(__func__);
4985
4986 return ret;
4987}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304988#endif /* WLAN_FEATURE_EXTSCAN */
4989
Atul Mittal115287b2014-07-08 13:26:33 +05304990/*EXT TDLS*/
4991static const struct nla_policy
4992wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4993{
4994 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4995 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4996 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4997 {.type = NLA_S32 },
4998 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4999 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5000
5001};
5002
5003static const struct nla_policy
5004wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5005{
5006 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
5007
5008};
5009
5010static const struct nla_policy
5011wlan_hdd_tdls_config_state_change_policy[
5012 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5013{
5014 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
5015 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5016 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305017 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5018 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5019 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305020
5021};
5022
5023static const struct nla_policy
5024wlan_hdd_tdls_config_get_status_policy[
5025 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5026{
5027 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
5028 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5029 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305030 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5031 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5032 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305033
5034};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305035
5036static const struct nla_policy
5037wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5038{
5039 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
5040};
5041
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305042static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305043 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305044 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305045 int data_len)
5046{
5047
5048 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5049 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5050
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305051 ENTER();
5052
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305053 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305054 return -EINVAL;
5055 }
5056 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305057 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305058 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305059 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305060 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305061 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305062 return -ENOTSUPP;
5063 }
5064
5065 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5066 data, data_len, wlan_hdd_mac_config)) {
5067 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5068 return -EINVAL;
5069 }
5070
5071 /* Parse and fetch mac address */
5072 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5073 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5074 return -EINVAL;
5075 }
5076
5077 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5078 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5079 VOS_MAC_ADDR_LAST_3_BYTES);
5080
Siddharth Bhal76972212014-10-15 16:22:51 +05305081 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5082
5083 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305084 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5085 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305086 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5087 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5088 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5089 {
5090 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5091 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5092 VOS_MAC_ADDRESS_LEN);
5093 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305094 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305095
Siddharth Bhal76972212014-10-15 16:22:51 +05305096 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
5097 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305098 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
5099 }
5100
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305101 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305102 return 0;
5103}
5104
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305105static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5106 struct wireless_dev *wdev,
5107 const void *data,
5108 int data_len)
5109{
5110 int ret = 0;
5111
5112 vos_ssr_protect(__func__);
5113 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5114 vos_ssr_unprotect(__func__);
5115
5116 return ret;
5117}
5118
5119static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305120 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305121 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305122 int data_len)
5123{
5124 u8 peer[6] = {0};
5125 struct net_device *dev = wdev->netdev;
5126 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5127 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5128 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5129 eHalStatus ret;
5130 tANI_S32 state;
5131 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305132 tANI_S32 global_operating_class = 0;
5133 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305134 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305135 int retVal;
5136
5137 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305138
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305139 if (!pAdapter) {
5140 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5141 return -EINVAL;
5142 }
5143
Atul Mittal115287b2014-07-08 13:26:33 +05305144 ret = wlan_hdd_validate_context(pHddCtx);
5145 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305146 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305147 return -EINVAL;
5148 }
5149 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305150 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305151 return -ENOTSUPP;
5152 }
5153 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5154 data, data_len,
5155 wlan_hdd_tdls_config_get_status_policy)) {
5156 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5157 return -EINVAL;
5158 }
5159
5160 /* Parse and fetch mac address */
5161 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5162 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5163 return -EINVAL;
5164 }
5165
5166 memcpy(peer, nla_data(
5167 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5168 sizeof(peer));
5169 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5170
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305171 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305172
Atul Mittal115287b2014-07-08 13:26:33 +05305173 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305174 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305175 NLMSG_HDRLEN);
5176
5177 if (!skb) {
5178 hddLog(VOS_TRACE_LEVEL_ERROR,
5179 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5180 return -EINVAL;
5181 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305182 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 +05305183 reason,
5184 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305185 global_operating_class,
5186 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305187 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305188 if (nla_put_s32(skb,
5189 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5190 state) ||
5191 nla_put_s32(skb,
5192 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5193 reason) ||
5194 nla_put_s32(skb,
5195 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5196 global_operating_class) ||
5197 nla_put_s32(skb,
5198 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5199 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305200
5201 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5202 goto nla_put_failure;
5203 }
5204
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305205 retVal = cfg80211_vendor_cmd_reply(skb);
5206 EXIT();
5207 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305208
5209nla_put_failure:
5210 kfree_skb(skb);
5211 return -EINVAL;
5212}
5213
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305214static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5215 struct wireless_dev *wdev,
5216 const void *data,
5217 int data_len)
5218{
5219 int ret = 0;
5220
5221 vos_ssr_protect(__func__);
5222 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5223 vos_ssr_unprotect(__func__);
5224
5225 return ret;
5226}
5227
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305228static int wlan_hdd_cfg80211_exttdls_callback(
5229#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5230 const tANI_U8* mac,
5231#else
5232 tANI_U8* mac,
5233#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305234 tANI_S32 state,
5235 tANI_S32 reason,
5236 void *ctx)
5237{
5238 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305239 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305240 tANI_S32 global_operating_class = 0;
5241 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305242 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305243
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305244 ENTER();
5245
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305246 if (!pAdapter) {
5247 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5248 return -EINVAL;
5249 }
5250
5251 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305252 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305253 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305254 return -EINVAL;
5255 }
5256
5257 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305258 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305259 return -ENOTSUPP;
5260 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305261 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5262#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5263 NULL,
5264#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305265 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5266 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5267 GFP_KERNEL);
5268
5269 if (!skb) {
5270 hddLog(VOS_TRACE_LEVEL_ERROR,
5271 FL("cfg80211_vendor_event_alloc failed"));
5272 return -EINVAL;
5273 }
5274 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305275 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5276 reason,
5277 state,
5278 global_operating_class,
5279 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305280 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5281 MAC_ADDR_ARRAY(mac));
5282
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305283 if (nla_put(skb,
5284 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5285 VOS_MAC_ADDR_SIZE, mac) ||
5286 nla_put_s32(skb,
5287 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5288 state) ||
5289 nla_put_s32(skb,
5290 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5291 reason) ||
5292 nla_put_s32(skb,
5293 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5294 channel) ||
5295 nla_put_s32(skb,
5296 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5297 global_operating_class)
5298 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305299 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5300 goto nla_put_failure;
5301 }
5302
5303 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305304 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305305 return (0);
5306
5307nla_put_failure:
5308 kfree_skb(skb);
5309 return -EINVAL;
5310}
5311
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305312static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305313 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305314 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305315 int data_len)
5316{
5317 u8 peer[6] = {0};
5318 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305319 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5320 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5321 eHalStatus status;
5322 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305323 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305324 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305325
5326 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305327
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305328 if (!dev) {
5329 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5330 return -EINVAL;
5331 }
5332
5333 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5334 if (!pAdapter) {
5335 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5336 return -EINVAL;
5337 }
5338
Atul Mittal115287b2014-07-08 13:26:33 +05305339 status = wlan_hdd_validate_context(pHddCtx);
5340 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305341 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305342 return -EINVAL;
5343 }
5344 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305345 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305346 return -ENOTSUPP;
5347 }
5348 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5349 data, data_len,
5350 wlan_hdd_tdls_config_enable_policy)) {
5351 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5352 return -EINVAL;
5353 }
5354
5355 /* Parse and fetch mac address */
5356 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5357 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5358 return -EINVAL;
5359 }
5360
5361 memcpy(peer, nla_data(
5362 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5363 sizeof(peer));
5364 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5365
5366 /* Parse and fetch channel */
5367 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5368 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5369 return -EINVAL;
5370 }
5371 pReqMsg.channel = nla_get_s32(
5372 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5373 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5374
5375 /* Parse and fetch global operating class */
5376 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5377 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5378 return -EINVAL;
5379 }
5380 pReqMsg.global_operating_class = nla_get_s32(
5381 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5382 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5383 pReqMsg.global_operating_class);
5384
5385 /* Parse and fetch latency ms */
5386 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5387 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5388 return -EINVAL;
5389 }
5390 pReqMsg.max_latency_ms = nla_get_s32(
5391 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5392 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5393 pReqMsg.max_latency_ms);
5394
5395 /* Parse and fetch required bandwidth kbps */
5396 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5397 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5398 return -EINVAL;
5399 }
5400
5401 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5402 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5403 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5404 pReqMsg.min_bandwidth_kbps);
5405
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305406 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305407 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305408 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305409 wlan_hdd_cfg80211_exttdls_callback);
5410
5411 EXIT();
5412 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305413}
5414
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305415static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5416 struct wireless_dev *wdev,
5417 const void *data,
5418 int data_len)
5419{
5420 int ret = 0;
5421
5422 vos_ssr_protect(__func__);
5423 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5424 vos_ssr_unprotect(__func__);
5425
5426 return ret;
5427}
5428
5429static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305430 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305431 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305432 int data_len)
5433{
5434 u8 peer[6] = {0};
5435 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305436 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5437 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5438 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305439 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305440 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305441
5442 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305443
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305444 if (!dev) {
5445 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5446 return -EINVAL;
5447 }
5448
5449 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5450 if (!pAdapter) {
5451 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5452 return -EINVAL;
5453 }
5454
Atul Mittal115287b2014-07-08 13:26:33 +05305455 status = wlan_hdd_validate_context(pHddCtx);
5456 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305458 return -EINVAL;
5459 }
5460 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305461 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305462 return -ENOTSUPP;
5463 }
5464 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5465 data, data_len,
5466 wlan_hdd_tdls_config_disable_policy)) {
5467 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5468 return -EINVAL;
5469 }
5470 /* Parse and fetch mac address */
5471 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5472 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5473 return -EINVAL;
5474 }
5475
5476 memcpy(peer, nla_data(
5477 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5478 sizeof(peer));
5479 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5480
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305481 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5482
5483 EXIT();
5484 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305485}
5486
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305487static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5488 struct wireless_dev *wdev,
5489 const void *data,
5490 int data_len)
5491{
5492 int ret = 0;
5493
5494 vos_ssr_protect(__func__);
5495 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5496 vos_ssr_unprotect(__func__);
5497
5498 return ret;
5499}
5500
Dasari Srinivas7875a302014-09-26 17:50:57 +05305501static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305502__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305503 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305504 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305505{
5506 struct net_device *dev = wdev->netdev;
5507 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5508 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5509 struct sk_buff *skb = NULL;
5510 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305511 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305512
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305513 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305514
5515 ret = wlan_hdd_validate_context(pHddCtx);
5516 if (0 != ret)
5517 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305518 return ret;
5519 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305520 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5521 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5522 fset |= WIFI_FEATURE_INFRA;
5523 }
5524
5525 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5526 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5527 fset |= WIFI_FEATURE_INFRA_5G;
5528 }
5529
5530#ifdef WLAN_FEATURE_P2P
5531 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5532 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5533 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5534 fset |= WIFI_FEATURE_P2P;
5535 }
5536#endif
5537
5538 /* Soft-AP is supported currently by default */
5539 fset |= WIFI_FEATURE_SOFT_AP;
5540
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305541 /* HOTSPOT is a supplicant feature, enable it by default */
5542 fset |= WIFI_FEATURE_HOTSPOT;
5543
Dasari Srinivas7875a302014-09-26 17:50:57 +05305544#ifdef WLAN_FEATURE_EXTSCAN
5545 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305546 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5547 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5548 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305549 fset |= WIFI_FEATURE_EXTSCAN;
5550 }
5551#endif
5552
Dasari Srinivas7875a302014-09-26 17:50:57 +05305553 if (sme_IsFeatureSupportedByFW(NAN)) {
5554 hddLog(LOG1, FL("NAN is supported by firmware"));
5555 fset |= WIFI_FEATURE_NAN;
5556 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305557
5558 /* D2D RTT is not supported currently by default */
5559 if (sme_IsFeatureSupportedByFW(RTT)) {
5560 hddLog(LOG1, FL("RTT is supported by firmware"));
5561 fset |= WIFI_FEATURE_D2AP_RTT;
5562 }
5563
5564#ifdef FEATURE_WLAN_BATCH_SCAN
5565 if (fset & WIFI_FEATURE_EXTSCAN) {
5566 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5567 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5568 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5569 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5570 fset |= WIFI_FEATURE_BATCH_SCAN;
5571 }
5572#endif
5573
5574#ifdef FEATURE_WLAN_SCAN_PNO
5575 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5576 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5577 hddLog(LOG1, FL("PNO is supported by firmware"));
5578 fset |= WIFI_FEATURE_PNO;
5579 }
5580#endif
5581
5582 /* STA+STA is supported currently by default */
5583 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5584
5585#ifdef FEATURE_WLAN_TDLS
5586 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5587 sme_IsFeatureSupportedByFW(TDLS)) {
5588 hddLog(LOG1, FL("TDLS is supported by firmware"));
5589 fset |= WIFI_FEATURE_TDLS;
5590 }
5591
5592 /* TDLS_OFFCHANNEL is not supported currently by default */
5593#endif
5594
5595#ifdef WLAN_AP_STA_CONCURRENCY
5596 /* AP+STA concurrency is supported currently by default */
5597 fset |= WIFI_FEATURE_AP_STA;
5598#endif
5599
Mukul Sharma5add0532015-08-17 15:57:47 +05305600#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5601 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5602 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5603#endif
5604
Dasari Srinivas7875a302014-09-26 17:50:57 +05305605 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5606 NLMSG_HDRLEN);
5607
5608 if (!skb) {
5609 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5610 return -EINVAL;
5611 }
5612 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5613
5614 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5615 hddLog(LOGE, FL("nla put fail"));
5616 goto nla_put_failure;
5617 }
5618
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305619 ret = cfg80211_vendor_cmd_reply(skb);
5620 EXIT();
5621 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305622
5623nla_put_failure:
5624 kfree_skb(skb);
5625 return -EINVAL;
5626}
5627
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305628static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305629wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5630 struct wireless_dev *wdev,
5631 const void *data, int data_len)
5632{
5633 int ret = 0;
5634
5635 vos_ssr_protect(__func__);
5636 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5637 vos_ssr_unprotect(__func__);
5638
5639 return ret;
5640}
5641
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305642
5643static const struct
5644nla_policy
5645qca_wlan_vendor_wifi_logger_get_ring_data_policy
5646[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5647 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5648 = {.type = NLA_U32 },
5649};
5650
5651static int
5652 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5653 struct wireless_dev *wdev,
5654 const void *data,
5655 int data_len)
5656{
5657 int ret;
5658 VOS_STATUS status;
5659 uint32_t ring_id;
5660 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5661 struct nlattr *tb
5662 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5663
5664 ENTER();
5665
5666 ret = wlan_hdd_validate_context(hdd_ctx);
5667 if (0 != ret) {
5668 return ret;
5669 }
5670
5671 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5672 data, data_len,
5673 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5674 hddLog(LOGE, FL("Invalid attribute"));
5675 return -EINVAL;
5676 }
5677
5678 /* Parse and fetch ring id */
5679 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5680 hddLog(LOGE, FL("attr ATTR failed"));
5681 return -EINVAL;
5682 }
5683
5684 ring_id = nla_get_u32(
5685 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5686
5687 hddLog(LOG1, FL("Bug report triggered by framework"));
5688
5689 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5690 WLAN_LOG_INDICATOR_FRAMEWORK,
5691 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305692 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305693 );
5694 if (VOS_STATUS_SUCCESS != status) {
5695 hddLog(LOGE, FL("Failed to trigger bug report"));
5696
5697 return -EINVAL;
5698 }
5699
5700 return 0;
5701
5702
5703}
5704
5705
5706static int
5707 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5708 struct wireless_dev *wdev,
5709 const void *data,
5710 int data_len)
5711{
5712 int ret = 0;
5713
5714 vos_ssr_protect(__func__);
5715 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5716 wdev, data, data_len);
5717 vos_ssr_unprotect(__func__);
5718
5719 return ret;
5720
5721}
5722
5723
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305724static int
5725__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305726 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305727 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305728{
5729 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5730 uint8_t i, feature_sets, max_feature_sets;
5731 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5732 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305733 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5734 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305735
5736 ENTER();
5737
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305738 ret = wlan_hdd_validate_context(pHddCtx);
5739 if (0 != ret)
5740 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305741 return ret;
5742 }
5743
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305744 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5745 data, data_len, NULL)) {
5746 hddLog(LOGE, FL("Invalid ATTR"));
5747 return -EINVAL;
5748 }
5749
5750 /* Parse and fetch max feature set */
5751 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5752 hddLog(LOGE, FL("Attr max feature set size failed"));
5753 return -EINVAL;
5754 }
5755 max_feature_sets = nla_get_u32(
5756 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5757 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5758
5759 /* Fill feature combination matrix */
5760 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305761 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5762 WIFI_FEATURE_P2P;
5763
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305764 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5765 WIFI_FEATURE_SOFT_AP;
5766
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305767 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5768 WIFI_FEATURE_SOFT_AP;
5769
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305770 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5771 WIFI_FEATURE_SOFT_AP |
5772 WIFI_FEATURE_P2P;
5773
5774 /* Add more feature combinations here */
5775
5776 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5777 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5778 hddLog(LOG1, "Feature set matrix");
5779 for (i = 0; i < feature_sets; i++)
5780 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5781
5782 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5783 sizeof(u32) * feature_sets +
5784 NLMSG_HDRLEN);
5785
5786 if (reply_skb) {
5787 if (nla_put_u32(reply_skb,
5788 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5789 feature_sets) ||
5790 nla_put(reply_skb,
5791 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5792 sizeof(u32) * feature_sets, feature_set_matrix)) {
5793 hddLog(LOGE, FL("nla put fail"));
5794 kfree_skb(reply_skb);
5795 return -EINVAL;
5796 }
5797
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305798 ret = cfg80211_vendor_cmd_reply(reply_skb);
5799 EXIT();
5800 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305801 }
5802 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5803 return -ENOMEM;
5804
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305805}
5806
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305807static int
5808wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5809 struct wireless_dev *wdev,
5810 const void *data, int data_len)
5811{
5812 int ret = 0;
5813
5814 vos_ssr_protect(__func__);
5815 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5816 data_len);
5817 vos_ssr_unprotect(__func__);
5818
5819 return ret;
5820}
5821
c_manjeecfd1efb2015-09-25 19:32:34 +05305822
5823static int
5824__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5825 struct wireless_dev *wdev,
5826 const void *data, int data_len)
5827{
5828 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5829 int ret;
5830 ENTER();
5831
5832 ret = wlan_hdd_validate_context(pHddCtx);
5833 if (0 != ret)
5834 {
5835 return ret;
5836 }
5837
5838 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5839 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5840 {
5841 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5842 return -EINVAL;
5843 }
5844 /*call common API for FW mem dump req*/
5845 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5846
5847 EXIT();
5848 return ret;
5849}
5850
5851/**
5852 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5853 * @wiphy: pointer to wireless wiphy structure.
5854 * @wdev: pointer to wireless_dev structure.
5855 * @data: Pointer to the NL data.
5856 * @data_len:Length of @data
5857 *
5858 * This is called when wlan driver needs to get the firmware memory dump
5859 * via vendor specific command.
5860 *
5861 * Return: 0 on success, error number otherwise.
5862 */
5863
5864static int
5865wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5866 struct wireless_dev *wdev,
5867 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305868{
5869 int ret = 0;
5870 vos_ssr_protect(__func__);
5871 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5872 data_len);
5873 vos_ssr_unprotect(__func__);
5874 return ret;
5875}
c_manjeecfd1efb2015-09-25 19:32:34 +05305876
Sushant Kaushik8e644982015-09-23 12:18:54 +05305877static const struct
5878nla_policy
5879qca_wlan_vendor_wifi_logger_start_policy
5880[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5881 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5882 = {.type = NLA_U32 },
5883 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5884 = {.type = NLA_U32 },
5885 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5886 = {.type = NLA_U32 },
5887};
5888
5889/**
5890 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5891 * or disable the collection of packet statistics from the firmware
5892 * @wiphy: WIPHY structure pointer
5893 * @wdev: Wireless device structure pointer
5894 * @data: Pointer to the data received
5895 * @data_len: Length of the data received
5896 *
5897 * This function is used to enable or disable the collection of packet
5898 * statistics from the firmware
5899 *
5900 * Return: 0 on success and errno on failure
5901 */
5902static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5903 struct wireless_dev *wdev,
5904 const void *data,
5905 int data_len)
5906{
5907 eHalStatus status;
5908 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5909 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5910 tAniWifiStartLog start_log;
5911
5912 status = wlan_hdd_validate_context(hdd_ctx);
5913 if (0 != status) {
5914 return -EINVAL;
5915 }
5916
5917 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5918 data, data_len,
5919 qca_wlan_vendor_wifi_logger_start_policy)) {
5920 hddLog(LOGE, FL("Invalid attribute"));
5921 return -EINVAL;
5922 }
5923
5924 /* Parse and fetch ring id */
5925 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5926 hddLog(LOGE, FL("attr ATTR failed"));
5927 return -EINVAL;
5928 }
5929 start_log.ringId = nla_get_u32(
5930 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5931 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5932
5933 /* Parse and fetch verbose level */
5934 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5935 hddLog(LOGE, FL("attr verbose_level failed"));
5936 return -EINVAL;
5937 }
5938 start_log.verboseLevel = nla_get_u32(
5939 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5940 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5941
5942 /* Parse and fetch flag */
5943 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5944 hddLog(LOGE, FL("attr flag failed"));
5945 return -EINVAL;
5946 }
5947 start_log.flag = nla_get_u32(
5948 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5949 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5950
5951 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305952 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5953 !vos_isPktStatsEnabled()))
5954
Sushant Kaushik8e644982015-09-23 12:18:54 +05305955 {
5956 hddLog(LOGE, FL("per pkt stats not enabled"));
5957 return -EINVAL;
5958 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305959
Sushant Kaushik33200572015-08-05 16:46:20 +05305960 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305961 return 0;
5962}
5963
5964/**
5965 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
5966 * or disable the collection of packet statistics from the firmware
5967 * @wiphy: WIPHY structure pointer
5968 * @wdev: Wireless device structure pointer
5969 * @data: Pointer to the data received
5970 * @data_len: Length of the data received
5971 *
5972 * This function is used to enable or disable the collection of packet
5973 * statistics from the firmware
5974 *
5975 * Return: 0 on success and errno on failure
5976 */
5977static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5978 struct wireless_dev *wdev,
5979 const void *data,
5980 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05305981{
5982 int ret = 0;
5983
5984 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305985
5986 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
5987 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05305988 vos_ssr_unprotect(__func__);
5989
5990 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05305991}
5992
5993
Agarwal Ashish738843c2014-09-25 12:27:56 +05305994static const struct nla_policy
5995wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5996 +1] =
5997{
5998 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5999};
6000
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306001static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306002 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05306003 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05306004 int data_len)
6005{
6006 struct net_device *dev = wdev->netdev;
6007 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6008 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6009 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6010 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
6011 eHalStatus status;
6012 u32 dfsFlag = 0;
6013
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306014 ENTER();
6015
Agarwal Ashish738843c2014-09-25 12:27:56 +05306016 status = wlan_hdd_validate_context(pHddCtx);
6017 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05306018 return -EINVAL;
6019 }
6020 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
6021 data, data_len,
6022 wlan_hdd_set_no_dfs_flag_config_policy)) {
6023 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6024 return -EINVAL;
6025 }
6026
6027 /* Parse and fetch required bandwidth kbps */
6028 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
6029 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
6030 return -EINVAL;
6031 }
6032
6033 dfsFlag = nla_get_u32(
6034 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
6035 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6036 dfsFlag);
6037
6038 pHddCtx->disable_dfs_flag = dfsFlag;
6039
6040 sme_disable_dfs_channel(hHal, dfsFlag);
6041 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306042
6043 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306044 return 0;
6045}
Atul Mittal115287b2014-07-08 13:26:33 +05306046
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306047static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6048 struct wireless_dev *wdev,
6049 const void *data,
6050 int data_len)
6051{
6052 int ret = 0;
6053
6054 vos_ssr_protect(__func__);
6055 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6056 vos_ssr_unprotect(__func__);
6057
6058 return ret;
6059
6060}
6061
Mukul Sharma2a271632014-10-13 14:59:01 +05306062const struct
6063nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6064{
6065 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
6066 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
6067};
6068
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306069static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306070 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306071{
6072
6073 u8 bssid[6] = {0};
6074 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6075 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6076 eHalStatus status = eHAL_STATUS_SUCCESS;
6077 v_U32_t isFwrRoamEnabled = FALSE;
6078 int ret;
6079
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306080 ENTER();
6081
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306082 ret = wlan_hdd_validate_context(pHddCtx);
6083 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306084 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306085 }
6086
6087 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6088 data, data_len,
6089 qca_wlan_vendor_attr);
6090 if (ret){
6091 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6092 return -EINVAL;
6093 }
6094
6095 /* Parse and fetch Enable flag */
6096 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6097 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6098 return -EINVAL;
6099 }
6100
6101 isFwrRoamEnabled = nla_get_u32(
6102 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6103
6104 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6105
6106 /* Parse and fetch bssid */
6107 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6108 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6109 return -EINVAL;
6110 }
6111
6112 memcpy(bssid, nla_data(
6113 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6114 sizeof(bssid));
6115 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6116
6117 //Update roaming
6118 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306119 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05306120 return status;
6121}
6122
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306123static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6124 struct wireless_dev *wdev, const void *data, int data_len)
6125{
6126 int ret = 0;
6127
6128 vos_ssr_protect(__func__);
6129 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6130 vos_ssr_unprotect(__func__);
6131
6132 return ret;
6133}
6134
Sushant Kaushik847890c2015-09-28 16:05:17 +05306135static const struct
6136nla_policy
6137qca_wlan_vendor_get_wifi_info_policy[
6138 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6139 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6140 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6141};
6142
6143
6144/**
6145 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6146 * @wiphy: pointer to wireless wiphy structure.
6147 * @wdev: pointer to wireless_dev structure.
6148 * @data: Pointer to the data to be passed via vendor interface
6149 * @data_len:Length of the data to be passed
6150 *
6151 * This is called when wlan driver needs to send wifi driver related info
6152 * (driver/fw version) to the user space application upon request.
6153 *
6154 * Return: Return the Success or Failure code.
6155 */
6156static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6157 struct wireless_dev *wdev,
6158 const void *data, int data_len)
6159{
6160 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6161 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6162 tSirVersionString version;
6163 uint32 version_len;
6164 uint8 attr;
6165 int status;
6166 struct sk_buff *reply_skb = NULL;
6167
6168 if (VOS_FTM_MODE == hdd_get_conparam()) {
6169 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6170 return -EINVAL;
6171 }
6172
6173 status = wlan_hdd_validate_context(hdd_ctx);
6174 if (0 != status) {
6175 hddLog(LOGE, FL("HDD context is not valid"));
6176 return -EINVAL;
6177 }
6178
6179 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6180 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6181 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6182 return -EINVAL;
6183 }
6184
6185 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6186 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6187 QWLAN_VERSIONSTR);
6188 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6189 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6190 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6191 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6192 hdd_ctx->fw_Version);
6193 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6194 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6195 } else {
6196 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6197 return -EINVAL;
6198 }
6199
6200 version_len = strlen(version);
6201 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6202 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6203 if (!reply_skb) {
6204 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6205 return -ENOMEM;
6206 }
6207
6208 if (nla_put(reply_skb, attr, version_len, version)) {
6209 hddLog(LOGE, FL("nla put fail"));
6210 kfree_skb(reply_skb);
6211 return -EINVAL;
6212 }
6213
6214 return cfg80211_vendor_cmd_reply(reply_skb);
6215}
6216
6217/**
6218 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6219 * @wiphy: pointer to wireless wiphy structure.
6220 * @wdev: pointer to wireless_dev structure.
6221 * @data: Pointer to the data to be passed via vendor interface
6222 * @data_len:Length of the data to be passed
6223 * @data_len: Length of the data received
6224 *
6225 * This function is used to enable or disable the collection of packet
6226 * statistics from the firmware
6227 *
6228 * Return: 0 on success and errno on failure
6229 */
6230
6231static int
6232wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6233 struct wireless_dev *wdev,
6234 const void *data, int data_len)
6235
6236
6237{
6238 int ret = 0;
6239
6240 vos_ssr_protect(__func__);
6241 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6242 wdev, data, data_len);
6243 vos_ssr_unprotect(__func__);
6244
6245 return ret;
6246}
6247
6248
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306249/*
6250 * define short names for the global vendor params
6251 * used by __wlan_hdd_cfg80211_monitor_rssi()
6252 */
6253#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6254#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6255#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6256#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6257#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6258
6259/**---------------------------------------------------------------------------
6260
6261 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6262 monitor start is completed successfully.
6263
6264 \return - None
6265
6266 --------------------------------------------------------------------------*/
6267void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6268{
6269 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6270
6271 if (NULL == pHddCtx)
6272 {
6273 hddLog(VOS_TRACE_LEVEL_ERROR,
6274 "%s: HDD context is NULL",__func__);
6275 return;
6276 }
6277
6278 if (VOS_STATUS_SUCCESS == status)
6279 {
6280 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6281 }
6282 else
6283 {
6284 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6285 }
6286
6287 return;
6288}
6289
6290/**---------------------------------------------------------------------------
6291
6292 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6293 stop is completed successfully.
6294
6295 \return - None
6296
6297 --------------------------------------------------------------------------*/
6298void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6299{
6300 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6301
6302 if (NULL == pHddCtx)
6303 {
6304 hddLog(VOS_TRACE_LEVEL_ERROR,
6305 "%s: HDD context is NULL",__func__);
6306 return;
6307 }
6308
6309 if (VOS_STATUS_SUCCESS == status)
6310 {
6311 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6312 }
6313 else
6314 {
6315 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6316 }
6317
6318 return;
6319}
6320
6321/**
6322 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6323 * @wiphy: Pointer to wireless phy
6324 * @wdev: Pointer to wireless device
6325 * @data: Pointer to data
6326 * @data_len: Data length
6327 *
6328 * Return: 0 on success, negative errno on failure
6329 */
6330
6331static int
6332__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6333 struct wireless_dev *wdev,
6334 const void *data,
6335 int data_len)
6336{
6337 struct net_device *dev = wdev->netdev;
6338 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6339 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6340 hdd_station_ctx_t *pHddStaCtx;
6341 struct nlattr *tb[PARAM_MAX + 1];
6342 tpSirRssiMonitorReq pReq;
6343 eHalStatus status;
6344 int ret;
6345 uint32_t control;
6346 static const struct nla_policy policy[PARAM_MAX + 1] = {
6347 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6348 [PARAM_CONTROL] = { .type = NLA_U32 },
6349 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6350 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6351 };
6352
6353 ENTER();
6354
6355 ret = wlan_hdd_validate_context(hdd_ctx);
6356 if (0 != ret) {
6357 return -EINVAL;
6358 }
6359
6360 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6361 hddLog(LOGE, FL("Not in Connected state!"));
6362 return -ENOTSUPP;
6363 }
6364
6365 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6366 hddLog(LOGE, FL("Invalid ATTR"));
6367 return -EINVAL;
6368 }
6369
6370 if (!tb[PARAM_REQUEST_ID]) {
6371 hddLog(LOGE, FL("attr request id failed"));
6372 return -EINVAL;
6373 }
6374
6375 if (!tb[PARAM_CONTROL]) {
6376 hddLog(LOGE, FL("attr control failed"));
6377 return -EINVAL;
6378 }
6379
6380 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6381
6382 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6383 if(NULL == pReq)
6384 {
6385 hddLog(LOGE,
6386 FL("vos_mem_alloc failed "));
6387 return eHAL_STATUS_FAILED_ALLOC;
6388 }
6389 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6390
6391 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6392 pReq->sessionId = pAdapter->sessionId;
6393 pReq->rssiMonitorCbContext = hdd_ctx;
6394 control = nla_get_u32(tb[PARAM_CONTROL]);
6395 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6396
6397 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6398 pReq->requestId, pReq->sessionId, control);
6399
6400 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6401 if (!tb[PARAM_MIN_RSSI]) {
6402 hddLog(LOGE, FL("attr min rssi failed"));
6403 return -EINVAL;
6404 }
6405
6406 if (!tb[PARAM_MAX_RSSI]) {
6407 hddLog(LOGE, FL("attr max rssi failed"));
6408 return -EINVAL;
6409 }
6410
6411 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6412 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6413 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6414
6415 if (!(pReq->minRssi < pReq->maxRssi)) {
6416 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6417 pReq->minRssi, pReq->maxRssi);
6418 return -EINVAL;
6419 }
6420 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6421 pReq->minRssi, pReq->maxRssi);
6422 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6423
6424 }
6425 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6426 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6427 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6428 }
6429 else {
6430 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
6431 return -EINVAL;
6432 }
6433
6434 if (!HAL_STATUS_SUCCESS(status)) {
6435 hddLog(LOGE,
6436 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
6437 return -EINVAL;
6438 }
6439
6440 return 0;
6441}
6442
6443/*
6444 * done with short names for the global vendor params
6445 * used by __wlan_hdd_cfg80211_monitor_rssi()
6446 */
6447#undef PARAM_MAX
6448#undef PARAM_CONTROL
6449#undef PARAM_REQUEST_ID
6450#undef PARAM_MAX_RSSI
6451#undef PARAM_MIN_RSSI
6452
6453/**
6454 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6455 * @wiphy: wiphy structure pointer
6456 * @wdev: Wireless device structure pointer
6457 * @data: Pointer to the data received
6458 * @data_len: Length of @data
6459 *
6460 * Return: 0 on success; errno on failure
6461 */
6462static int
6463wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6464 const void *data, int data_len)
6465{
6466 int ret;
6467
6468 vos_ssr_protect(__func__);
6469 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6470 vos_ssr_unprotect(__func__);
6471
6472 return ret;
6473}
6474
6475/**
6476 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6477 * @hddctx: HDD context
6478 * @data: rssi breached event data
6479 *
6480 * This function reads the rssi breached event %data and fill in the skb with
6481 * NL attributes and send up the NL event.
6482 * This callback execute in atomic context and must not invoke any
6483 * blocking calls.
6484 *
6485 * Return: none
6486 */
6487void hdd_rssi_threshold_breached_cb(void *hddctx,
6488 struct rssi_breach_event *data)
6489{
6490 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6491 int status;
6492 struct sk_buff *skb;
6493
6494 ENTER();
6495 status = wlan_hdd_validate_context(pHddCtx);
6496
6497 if (0 != status) {
6498 return;
6499 }
6500
6501 if (!data) {
6502 hddLog(LOGE, FL("data is null"));
6503 return;
6504 }
6505
6506 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6507#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6508 NULL,
6509#endif
6510 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6511 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6512 GFP_KERNEL);
6513
6514 if (!skb) {
6515 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6516 return;
6517 }
6518
6519 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6520 data->request_id, data->curr_rssi);
6521 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6522 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6523
6524 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6525 data->request_id) ||
6526 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6527 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6528 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6529 data->curr_rssi)) {
6530 hddLog(LOGE, FL("nla put fail"));
6531 goto fail;
6532 }
6533
6534 cfg80211_vendor_event(skb, GFP_KERNEL);
6535 return;
6536
6537fail:
6538 kfree_skb(skb);
6539 return;
6540}
6541
6542
6543
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306544/**
6545 * __wlan_hdd_cfg80211_setband() - set band
6546 * @wiphy: Pointer to wireless phy
6547 * @wdev: Pointer to wireless device
6548 * @data: Pointer to data
6549 * @data_len: Data length
6550 *
6551 * Return: 0 on success, negative errno on failure
6552 */
6553static int
6554__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6555 struct wireless_dev *wdev,
6556 const void *data,
6557 int data_len)
6558{
6559 struct net_device *dev = wdev->netdev;
6560 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6561 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6562 int ret;
6563 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6564 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6565
6566 ENTER();
6567
6568 ret = wlan_hdd_validate_context(hdd_ctx);
6569 if (0 != ret) {
6570 hddLog(LOGE, FL("HDD context is not valid"));
6571 return ret;
6572 }
6573
6574 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6575 policy)) {
6576 hddLog(LOGE, FL("Invalid ATTR"));
6577 return -EINVAL;
6578 }
6579
6580 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6581 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6582 return -EINVAL;
6583 }
6584
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306585 hdd_ctx->isSetBandByNL = TRUE;
6586 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306587 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306588 hdd_ctx->isSetBandByNL = FALSE;
6589
6590 EXIT();
6591 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306592}
6593
6594/**
6595 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6596 * @wiphy: wiphy structure pointer
6597 * @wdev: Wireless device structure pointer
6598 * @data: Pointer to the data received
6599 * @data_len: Length of @data
6600 *
6601 * Return: 0 on success; errno on failure
6602 */
6603static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6604 struct wireless_dev *wdev,
6605 const void *data,
6606 int data_len)
6607{
6608 int ret = 0;
6609
6610 vos_ssr_protect(__func__);
6611 ret = __wlan_hdd_cfg80211_setband(wiphy,
6612 wdev, data, data_len);
6613 vos_ssr_unprotect(__func__);
6614
6615 return ret;
6616}
6617
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306618#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6619/**
6620 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6621 * @hdd_ctx: HDD context
6622 * @request_id: [input] request id
6623 * @pattern_id: [output] pattern id
6624 *
6625 * This function loops through request id to pattern id array
6626 * if the slot is available, store the request id and return pattern id
6627 * if entry exists, return the pattern id
6628 *
6629 * Return: 0 on success and errno on failure
6630 */
6631static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6632 uint32_t request_id,
6633 uint8_t *pattern_id)
6634{
6635 uint32_t i;
6636
6637 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6638 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6639 {
6640 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6641 {
6642 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6643 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6644 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6645 return 0;
6646 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6647 request_id) {
6648 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6649 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6650 return 0;
6651 }
6652 }
6653 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6654 return -EINVAL;
6655}
6656
6657/**
6658 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6659 * @hdd_ctx: HDD context
6660 * @request_id: [input] request id
6661 * @pattern_id: [output] pattern id
6662 *
6663 * This function loops through request id to pattern id array
6664 * reset request id to 0 (slot available again) and
6665 * return pattern id
6666 *
6667 * Return: 0 on success and errno on failure
6668 */
6669static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6670 uint32_t request_id,
6671 uint8_t *pattern_id)
6672{
6673 uint32_t i;
6674
6675 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6676 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6677 {
6678 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6679 {
6680 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6681 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6682 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6683 return 0;
6684 }
6685 }
6686 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6687 return -EINVAL;
6688}
6689
6690
6691/*
6692 * define short names for the global vendor params
6693 * used by __wlan_hdd_cfg80211_offloaded_packets()
6694 */
6695#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6696#define PARAM_REQUEST_ID \
6697 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6698#define PARAM_CONTROL \
6699 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6700#define PARAM_IP_PACKET \
6701 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6702#define PARAM_SRC_MAC_ADDR \
6703 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6704#define PARAM_DST_MAC_ADDR \
6705 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6706#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6707
6708/**
6709 * wlan_hdd_add_tx_ptrn() - add tx pattern
6710 * @adapter: adapter pointer
6711 * @hdd_ctx: hdd context
6712 * @tb: nl attributes
6713 *
6714 * This function reads the NL attributes and forms a AddTxPtrn message
6715 * posts it to SME.
6716 *
6717 */
6718static int
6719wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6720 struct nlattr **tb)
6721{
6722 struct sSirAddPeriodicTxPtrn *add_req;
6723 eHalStatus status;
6724 uint32_t request_id, ret, len;
6725 uint8_t pattern_id = 0;
6726 v_MACADDR_t dst_addr;
6727 uint16_t eth_type = htons(ETH_P_IP);
6728
6729 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6730 {
6731 hddLog(LOGE, FL("Not in Connected state!"));
6732 return -ENOTSUPP;
6733 }
6734
6735 add_req = vos_mem_malloc(sizeof(*add_req));
6736 if (!add_req)
6737 {
6738 hddLog(LOGE, FL("memory allocation failed"));
6739 return -ENOMEM;
6740 }
6741
6742 /* Parse and fetch request Id */
6743 if (!tb[PARAM_REQUEST_ID])
6744 {
6745 hddLog(LOGE, FL("attr request id failed"));
6746 goto fail;
6747 }
6748
6749 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6750 hddLog(LOG1, FL("Request Id: %u"), request_id);
6751 if (request_id == 0)
6752 {
6753 hddLog(LOGE, FL("request_id cannot be zero"));
6754 return -EINVAL;
6755 }
6756
6757 if (!tb[PARAM_PERIOD])
6758 {
6759 hddLog(LOGE, FL("attr period failed"));
6760 goto fail;
6761 }
6762 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6763 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6764 if (add_req->usPtrnIntervalMs == 0)
6765 {
6766 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6767 goto fail;
6768 }
6769
6770 if (!tb[PARAM_SRC_MAC_ADDR])
6771 {
6772 hddLog(LOGE, FL("attr source mac address failed"));
6773 goto fail;
6774 }
6775 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6776 VOS_MAC_ADDR_SIZE);
6777 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6778 MAC_ADDR_ARRAY(add_req->macAddress));
6779
6780 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6781 VOS_MAC_ADDR_SIZE))
6782 {
6783 hddLog(LOGE,
6784 FL("input src mac address and connected ap bssid are different"));
6785 goto fail;
6786 }
6787
6788 if (!tb[PARAM_DST_MAC_ADDR])
6789 {
6790 hddLog(LOGE, FL("attr dst mac address failed"));
6791 goto fail;
6792 }
6793 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6794 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6795 MAC_ADDR_ARRAY(dst_addr.bytes));
6796
6797 if (!tb[PARAM_IP_PACKET])
6798 {
6799 hddLog(LOGE, FL("attr ip packet failed"));
6800 goto fail;
6801 }
6802 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6803 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6804
6805 if (add_req->ucPtrnSize < 0 ||
6806 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6807 HDD_ETH_HEADER_LEN))
6808 {
6809 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6810 add_req->ucPtrnSize);
6811 goto fail;
6812 }
6813
6814 len = 0;
6815 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6816 len += VOS_MAC_ADDR_SIZE;
6817 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6818 VOS_MAC_ADDR_SIZE);
6819 len += VOS_MAC_ADDR_SIZE;
6820 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6821 len += 2;
6822
6823 /*
6824 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6825 * ------------------------------------------------------------
6826 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6827 * ------------------------------------------------------------
6828 */
6829 vos_mem_copy(&add_req->ucPattern[len],
6830 nla_data(tb[PARAM_IP_PACKET]),
6831 add_req->ucPtrnSize);
6832 add_req->ucPtrnSize += len;
6833
6834 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6835 add_req->ucPattern, add_req->ucPtrnSize);
6836
6837 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6838 if (ret)
6839 {
6840 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6841 goto fail;
6842 }
6843 add_req->ucPtrnId = pattern_id;
6844 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6845
6846 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6847 if (!HAL_STATUS_SUCCESS(status))
6848 {
6849 hddLog(LOGE,
6850 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6851 goto fail;
6852 }
6853
6854 EXIT();
6855 vos_mem_free(add_req);
6856 return 0;
6857
6858fail:
6859 vos_mem_free(add_req);
6860 return -EINVAL;
6861}
6862
6863/**
6864 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6865 * @adapter: adapter pointer
6866 * @hdd_ctx: hdd context
6867 * @tb: nl attributes
6868 *
6869 * This function reads the NL attributes and forms a DelTxPtrn message
6870 * posts it to SME.
6871 *
6872 */
6873static int
6874wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6875 struct nlattr **tb)
6876{
6877 struct sSirDelPeriodicTxPtrn *del_req;
6878 eHalStatus status;
6879 uint32_t request_id, ret;
6880 uint8_t pattern_id = 0;
6881
6882 /* Parse and fetch request Id */
6883 if (!tb[PARAM_REQUEST_ID])
6884 {
6885 hddLog(LOGE, FL("attr request id failed"));
6886 return -EINVAL;
6887 }
6888 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6889 if (request_id == 0)
6890 {
6891 hddLog(LOGE, FL("request_id cannot be zero"));
6892 return -EINVAL;
6893 }
6894
6895 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6896 if (ret)
6897 {
6898 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6899 return -EINVAL;
6900 }
6901
6902 del_req = vos_mem_malloc(sizeof(*del_req));
6903 if (!del_req)
6904 {
6905 hddLog(LOGE, FL("memory allocation failed"));
6906 return -ENOMEM;
6907 }
6908
6909 vos_mem_set(del_req, sizeof(*del_req), 0);
6910 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6911 VOS_MAC_ADDR_SIZE);
6912 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6913 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6914 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6915 request_id, pattern_id, del_req->ucPatternIdBitmap);
6916
6917 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6918 if (!HAL_STATUS_SUCCESS(status))
6919 {
6920 hddLog(LOGE,
6921 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6922 goto fail;
6923 }
6924
6925 EXIT();
6926 vos_mem_free(del_req);
6927 return 0;
6928
6929fail:
6930 vos_mem_free(del_req);
6931 return -EINVAL;
6932}
6933
6934
6935/**
6936 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
6937 * @wiphy: Pointer to wireless phy
6938 * @wdev: Pointer to wireless device
6939 * @data: Pointer to data
6940 * @data_len: Data length
6941 *
6942 * Return: 0 on success, negative errno on failure
6943 */
6944static int
6945__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6946 struct wireless_dev *wdev,
6947 const void *data,
6948 int data_len)
6949{
6950 struct net_device *dev = wdev->netdev;
6951 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6952 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6953 struct nlattr *tb[PARAM_MAX + 1];
6954 uint8_t control;
6955 int ret;
6956 static const struct nla_policy policy[PARAM_MAX + 1] =
6957 {
6958 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6959 [PARAM_CONTROL] = { .type = NLA_U32 },
6960 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
6961 .len = VOS_MAC_ADDR_SIZE },
6962 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
6963 .len = VOS_MAC_ADDR_SIZE },
6964 [PARAM_PERIOD] = { .type = NLA_U32 },
6965 };
6966
6967 ENTER();
6968
6969 ret = wlan_hdd_validate_context(hdd_ctx);
6970 if (0 != ret)
6971 {
6972 hddLog(LOGE, FL("HDD context is not valid"));
6973 return ret;
6974 }
6975
6976 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
6977 {
6978 hddLog(LOGE,
6979 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
6980 return -ENOTSUPP;
6981 }
6982
6983 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
6984 {
6985 hddLog(LOGE, FL("Invalid ATTR"));
6986 return -EINVAL;
6987 }
6988
6989 if (!tb[PARAM_CONTROL])
6990 {
6991 hddLog(LOGE, FL("attr control failed"));
6992 return -EINVAL;
6993 }
6994 control = nla_get_u32(tb[PARAM_CONTROL]);
6995 hddLog(LOG1, FL("Control: %d"), control);
6996
6997 if (control == WLAN_START_OFFLOADED_PACKETS)
6998 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
6999 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
7000 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
7001 else
7002 {
7003 hddLog(LOGE, FL("Invalid control: %d"), control);
7004 return -EINVAL;
7005 }
7006}
7007
7008/*
7009 * done with short names for the global vendor params
7010 * used by __wlan_hdd_cfg80211_offloaded_packets()
7011 */
7012#undef PARAM_MAX
7013#undef PARAM_REQUEST_ID
7014#undef PARAM_CONTROL
7015#undef PARAM_IP_PACKET
7016#undef PARAM_SRC_MAC_ADDR
7017#undef PARAM_DST_MAC_ADDR
7018#undef PARAM_PERIOD
7019
7020/**
7021 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
7022 * @wiphy: wiphy structure pointer
7023 * @wdev: Wireless device structure pointer
7024 * @data: Pointer to the data received
7025 * @data_len: Length of @data
7026 *
7027 * Return: 0 on success; errno on failure
7028 */
7029static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
7030 struct wireless_dev *wdev,
7031 const void *data,
7032 int data_len)
7033{
7034 int ret = 0;
7035
7036 vos_ssr_protect(__func__);
7037 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7038 wdev, data, data_len);
7039 vos_ssr_unprotect(__func__);
7040
7041 return ret;
7042}
7043#endif
7044
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307045static const struct
7046nla_policy
7047qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
7048 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
7049};
7050
7051/**
7052 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7053 * get link properties like nss, rate flags and operating frequency for
7054 * the connection with the given peer.
7055 * @wiphy: WIPHY structure pointer
7056 * @wdev: Wireless device structure pointer
7057 * @data: Pointer to the data received
7058 * @data_len: Length of the data received
7059 *
7060 * This function return the above link properties on success.
7061 *
7062 * Return: 0 on success and errno on failure
7063 */
7064static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7065 struct wireless_dev *wdev,
7066 const void *data,
7067 int data_len)
7068{
7069 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7070 struct net_device *dev = wdev->netdev;
7071 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7072 hdd_station_ctx_t *hdd_sta_ctx;
7073 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7074 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7075 uint32_t sta_id;
7076 struct sk_buff *reply_skb;
7077 uint32_t rate_flags = 0;
7078 uint8_t nss;
7079 uint8_t final_rate_flags = 0;
7080 uint32_t freq;
7081 v_CONTEXT_t pVosContext = NULL;
7082 ptSapContext pSapCtx = NULL;
7083
7084 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7085 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7086 return -EINVAL;
7087 }
7088
7089 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7090 qca_wlan_vendor_attr_policy)) {
7091 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7092 return -EINVAL;
7093 }
7094
7095 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7096 hddLog(VOS_TRACE_LEVEL_ERROR,
7097 FL("Attribute peerMac not provided for mode=%d"),
7098 adapter->device_mode);
7099 return -EINVAL;
7100 }
7101
7102 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7103 sizeof(peer_mac));
7104 hddLog(VOS_TRACE_LEVEL_INFO,
7105 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7106 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7107
7108 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7109 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7110 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7111 if ((hdd_sta_ctx->conn_info.connState !=
7112 eConnectionState_Associated) ||
7113 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7114 VOS_MAC_ADDRESS_LEN)) {
7115 hddLog(VOS_TRACE_LEVEL_ERROR,
7116 FL("Not Associated to mac "MAC_ADDRESS_STR),
7117 MAC_ADDR_ARRAY(peer_mac));
7118 return -EINVAL;
7119 }
7120
7121 nss = 1; //pronto supports only one spatial stream
7122 freq = vos_chan_to_freq(
7123 hdd_sta_ctx->conn_info.operationChannel);
7124 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7125
7126 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7127 adapter->device_mode == WLAN_HDD_SOFTAP) {
7128
7129 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7130 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7131 if(pSapCtx == NULL){
7132 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7133 FL("psapCtx is NULL"));
7134 return -ENOENT;
7135 }
7136
7137
7138 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7139 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7140 !vos_is_macaddr_broadcast(
7141 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7142 vos_mem_compare(
7143 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7144 peer_mac, VOS_MAC_ADDRESS_LEN))
7145 break;
7146 }
7147
7148 if (WLAN_MAX_STA_COUNT == sta_id) {
7149 hddLog(VOS_TRACE_LEVEL_ERROR,
7150 FL("No active peer with mac="MAC_ADDRESS_STR),
7151 MAC_ADDR_ARRAY(peer_mac));
7152 return -EINVAL;
7153 }
7154
7155 nss = 1; //pronto supports only one spatial stream
7156 freq = vos_chan_to_freq(
7157 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7158 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7159 } else {
7160 hddLog(VOS_TRACE_LEVEL_ERROR,
7161 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7162 MAC_ADDR_ARRAY(peer_mac));
7163 return -EINVAL;
7164 }
7165
7166 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7167 if (rate_flags & eHAL_TX_RATE_VHT80) {
7168 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7169 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7170 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7171 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7172 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7173 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7174 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7175 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7176 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7177 if (rate_flags & eHAL_TX_RATE_HT40)
7178 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7179 }
7180
7181 if (rate_flags & eHAL_TX_RATE_SGI) {
7182 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7183 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7184 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7185 }
7186 }
7187
7188 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7189 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7190
7191 if (NULL == reply_skb) {
7192 hddLog(VOS_TRACE_LEVEL_ERROR,
7193 FL("getLinkProperties: skb alloc failed"));
7194 return -EINVAL;
7195 }
7196
7197 if (nla_put_u8(reply_skb,
7198 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7199 nss) ||
7200 nla_put_u8(reply_skb,
7201 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7202 final_rate_flags) ||
7203 nla_put_u32(reply_skb,
7204 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7205 freq)) {
7206 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7207 kfree_skb(reply_skb);
7208 return -EINVAL;
7209 }
7210
7211 return cfg80211_vendor_cmd_reply(reply_skb);
7212}
7213
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307214#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7215#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7216#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7217#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
7218
7219/**
7220 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7221 * vendor command
7222 *
7223 * @wiphy: wiphy device pointer
7224 * @wdev: wireless device pointer
7225 * @data: Vendor command data buffer
7226 * @data_len: Buffer length
7227 *
7228 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7229 *
7230 * Return: EOK or other error codes.
7231 */
7232
7233static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7234 struct wireless_dev *wdev,
7235 const void *data,
7236 int data_len)
7237{
7238 struct net_device *dev = wdev->netdev;
7239 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7240 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7241 hdd_station_ctx_t *pHddStaCtx;
7242 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7243 tpSetWifiConfigParams pReq;
7244 eHalStatus status;
7245 int ret_val;
7246 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7247 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7248 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
7249 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7250 };
7251
7252 ENTER();
7253
7254 if (VOS_FTM_MODE == hdd_get_conparam()) {
7255 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7256 return -EINVAL;
7257 }
7258
7259 ret_val = wlan_hdd_validate_context(pHddCtx);
7260 if (ret_val) {
7261 return ret_val;
7262 }
7263
7264 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7265
7266 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7267 hddLog(LOGE, FL("Not in Connected state!"));
7268 return -ENOTSUPP;
7269 }
7270
7271 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7272 hddLog(LOGE, FL("Invalid ATTR"));
7273 return -EINVAL;
7274 }
7275
7276 /* check the Wifi Capability */
7277 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7278 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7279 {
7280 hddLog(VOS_TRACE_LEVEL_ERROR,
7281 FL("WIFICONFIG not supported by Firmware"));
7282 return -EINVAL;
7283 }
7284
7285 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
7286
7287 if (!pReq) {
7288 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7289 "%s: Not able to allocate memory for tSetWifiConfigParams",
7290 __func__);
7291 return eHAL_STATUS_E_MALLOC_FAILED;
7292 }
7293
7294 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7295
7296 pReq->sessionId = pAdapter->sessionId;
7297 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7298
7299 if (tb[PARAM_MODULATED_DTIM]) {
7300 pReq->paramValue = nla_get_u32(
7301 tb[PARAM_MODULATED_DTIM]);
7302 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7303 pReq->paramValue);
7304 pHddCtx->cfg_ini->fMaxLIModulatedDTIM = pReq->paramValue;
7305 hdd_set_pwrparams(pHddCtx);
7306 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7307 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7308
7309 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7310 iw_full_power_cbfn, pAdapter,
7311 eSME_FULL_PWR_NEEDED_BY_HDD);
7312 }
7313 else
7314 {
7315 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7316 }
7317 }
7318
7319 if (tb[PARAM_STATS_AVG_FACTOR]) {
7320 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7321 pReq->paramValue = nla_get_u16(
7322 tb[PARAM_STATS_AVG_FACTOR]);
7323 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7324 pReq->paramType, pReq->paramValue);
7325 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7326
7327 if (eHAL_STATUS_SUCCESS != status)
7328 {
7329 vos_mem_free(pReq);
7330 pReq = NULL;
7331 ret_val = -EPERM;
7332 return ret_val;
7333 }
7334 }
7335
7336
7337 if (tb[PARAM_GUARD_TIME]) {
7338 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7339 pReq->paramValue = nla_get_u32(
7340 tb[PARAM_GUARD_TIME]);
7341 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7342 pReq->paramType, pReq->paramValue);
7343 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7344
7345 if (eHAL_STATUS_SUCCESS != status)
7346 {
7347 vos_mem_free(pReq);
7348 pReq = NULL;
7349 ret_val = -EPERM;
7350 return ret_val;
7351 }
7352
7353 }
7354
7355 EXIT();
7356 return ret_val;
7357}
7358
7359/**
7360 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7361 * vendor command
7362 *
7363 * @wiphy: wiphy device pointer
7364 * @wdev: wireless device pointer
7365 * @data: Vendor command data buffer
7366 * @data_len: Buffer length
7367 *
7368 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7369 *
7370 * Return: EOK or other error codes.
7371 */
7372static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7373 struct wireless_dev *wdev,
7374 const void *data,
7375 int data_len)
7376{
7377 int ret;
7378
7379 vos_ssr_protect(__func__);
7380 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7381 data, data_len);
7382 vos_ssr_unprotect(__func__);
7383
7384 return ret;
7385}
Sunil Duttc69bccb2014-05-26 21:30:20 +05307386const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7387{
Mukul Sharma2a271632014-10-13 14:59:01 +05307388 {
7389 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7390 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7391 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7392 WIPHY_VENDOR_CMD_NEED_NETDEV |
7393 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307394 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307395 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307396
7397 {
7398 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7399 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7400 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7401 WIPHY_VENDOR_CMD_NEED_NETDEV |
7402 WIPHY_VENDOR_CMD_NEED_RUNNING,
7403 .doit = wlan_hdd_cfg80211_nan_request
7404 },
7405
Sunil Duttc69bccb2014-05-26 21:30:20 +05307406#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7407 {
7408 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7409 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7410 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7411 WIPHY_VENDOR_CMD_NEED_NETDEV |
7412 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307413 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307414 },
7415
7416 {
7417 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7418 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7419 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7420 WIPHY_VENDOR_CMD_NEED_NETDEV |
7421 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307422 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307423 },
7424
7425 {
7426 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7427 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7428 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7429 WIPHY_VENDOR_CMD_NEED_NETDEV |
7430 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307431 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307432 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307433#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307434#ifdef WLAN_FEATURE_EXTSCAN
7435 {
7436 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7437 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
7438 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7439 WIPHY_VENDOR_CMD_NEED_NETDEV |
7440 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307441 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05307442 },
7443 {
7444 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7445 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
7446 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7447 WIPHY_VENDOR_CMD_NEED_NETDEV |
7448 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307449 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05307450 },
7451 {
7452 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7453 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
7454 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7455 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307456 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05307457 },
7458 {
7459 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7460 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
7461 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7462 WIPHY_VENDOR_CMD_NEED_NETDEV |
7463 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307464 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05307465 },
7466 {
7467 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7468 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
7469 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7470 WIPHY_VENDOR_CMD_NEED_NETDEV |
7471 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307472 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05307473 },
7474 {
7475 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7476 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
7477 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7478 WIPHY_VENDOR_CMD_NEED_NETDEV |
7479 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307480 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307481 },
7482 {
7483 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7484 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
7485 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7486 WIPHY_VENDOR_CMD_NEED_NETDEV |
7487 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307488 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307489 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307490 {
7491 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7492 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
7493 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7494 WIPHY_VENDOR_CMD_NEED_NETDEV |
7495 WIPHY_VENDOR_CMD_NEED_RUNNING,
7496 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
7497 },
7498 {
7499 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7500 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
7501 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7502 WIPHY_VENDOR_CMD_NEED_NETDEV |
7503 WIPHY_VENDOR_CMD_NEED_RUNNING,
7504 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
7505 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307506#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307507/*EXT TDLS*/
7508 {
7509 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7510 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
7511 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7512 WIPHY_VENDOR_CMD_NEED_NETDEV |
7513 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307514 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05307515 },
7516 {
7517 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7518 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
7519 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7520 WIPHY_VENDOR_CMD_NEED_NETDEV |
7521 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307522 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05307523 },
7524 {
7525 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7526 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
7527 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7528 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307529 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05307530 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05307531 {
7532 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7533 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
7534 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7535 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307536 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05307537 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05307538 {
7539 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7540 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
7541 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7542 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307543 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05307544 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307545 {
7546 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7547 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
7548 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7549 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307550 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307551 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307552 {
7553 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7554 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
7555 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7556 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307557 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307558 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307559 {
7560 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05307561 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
7562 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7563 WIPHY_VENDOR_CMD_NEED_NETDEV |
7564 WIPHY_VENDOR_CMD_NEED_RUNNING,
7565 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
7566 },
7567 {
7568 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307569 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
7570 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7571 WIPHY_VENDOR_CMD_NEED_NETDEV |
7572 WIPHY_VENDOR_CMD_NEED_RUNNING,
7573 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05307574 },
7575 {
7576 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7577 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
7578 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7579 WIPHY_VENDOR_CMD_NEED_NETDEV,
7580 .doit = wlan_hdd_cfg80211_wifi_logger_start
7581 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05307582 {
7583 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7584 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
7585 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7586 WIPHY_VENDOR_CMD_NEED_NETDEV|
7587 WIPHY_VENDOR_CMD_NEED_RUNNING,
7588 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05307589 },
7590 {
7591 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7592 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
7593 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7594 WIPHY_VENDOR_CMD_NEED_NETDEV |
7595 WIPHY_VENDOR_CMD_NEED_RUNNING,
7596 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307597 },
7598 {
7599 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7600 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
7601 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7602 WIPHY_VENDOR_CMD_NEED_NETDEV |
7603 WIPHY_VENDOR_CMD_NEED_RUNNING,
7604 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307605 },
7606#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7607 {
7608 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7609 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
7610 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7611 WIPHY_VENDOR_CMD_NEED_NETDEV |
7612 WIPHY_VENDOR_CMD_NEED_RUNNING,
7613 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307614 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307615#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307616 {
7617 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7618 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
7619 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7620 WIPHY_VENDOR_CMD_NEED_NETDEV |
7621 WIPHY_VENDOR_CMD_NEED_RUNNING,
7622 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307623 },
7624 {
7625 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7626 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
7627 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7628 WIPHY_VENDOR_CMD_NEED_NETDEV |
7629 WIPHY_VENDOR_CMD_NEED_RUNNING,
7630 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307631 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05307632};
7633
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007634/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307635static const
7636struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007637{
7638#ifdef FEATURE_WLAN_CH_AVOID
7639 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05307640 .vendor_id = QCA_NL80211_VENDOR_ID,
7641 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007642 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307643#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
7644#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7645 {
7646 /* Index = 1*/
7647 .vendor_id = QCA_NL80211_VENDOR_ID,
7648 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
7649 },
7650 {
7651 /* Index = 2*/
7652 .vendor_id = QCA_NL80211_VENDOR_ID,
7653 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
7654 },
7655 {
7656 /* Index = 3*/
7657 .vendor_id = QCA_NL80211_VENDOR_ID,
7658 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
7659 },
7660 {
7661 /* Index = 4*/
7662 .vendor_id = QCA_NL80211_VENDOR_ID,
7663 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
7664 },
7665 {
7666 /* Index = 5*/
7667 .vendor_id = QCA_NL80211_VENDOR_ID,
7668 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
7669 },
7670 {
7671 /* Index = 6*/
7672 .vendor_id = QCA_NL80211_VENDOR_ID,
7673 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
7674 },
7675#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307676#ifdef WLAN_FEATURE_EXTSCAN
7677 {
7678 .vendor_id = QCA_NL80211_VENDOR_ID,
7679 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
7680 },
7681 {
7682 .vendor_id = QCA_NL80211_VENDOR_ID,
7683 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
7684 },
7685 {
7686 .vendor_id = QCA_NL80211_VENDOR_ID,
7687 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
7688 },
7689 {
7690 .vendor_id = QCA_NL80211_VENDOR_ID,
7691 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
7692 },
7693 {
7694 .vendor_id = QCA_NL80211_VENDOR_ID,
7695 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
7696 },
7697 {
7698 .vendor_id = QCA_NL80211_VENDOR_ID,
7699 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
7700 },
7701 {
7702 .vendor_id = QCA_NL80211_VENDOR_ID,
7703 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
7704 },
7705 {
7706 .vendor_id = QCA_NL80211_VENDOR_ID,
7707 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
7708 },
7709 {
7710 .vendor_id = QCA_NL80211_VENDOR_ID,
7711 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
7712 },
7713 {
7714 .vendor_id = QCA_NL80211_VENDOR_ID,
7715 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
7716 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307717 {
7718 .vendor_id = QCA_NL80211_VENDOR_ID,
7719 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
7720 },
7721 {
7722 .vendor_id = QCA_NL80211_VENDOR_ID,
7723 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
7724 },
7725 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
7726 .vendor_id = QCA_NL80211_VENDOR_ID,
7727 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
7728 },
7729 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
7730 .vendor_id = QCA_NL80211_VENDOR_ID,
7731 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
7732 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307733#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307734/*EXT TDLS*/
7735 {
7736 .vendor_id = QCA_NL80211_VENDOR_ID,
7737 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
7738 },
c_manjeecfd1efb2015-09-25 19:32:34 +05307739 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
7740 .vendor_id = QCA_NL80211_VENDOR_ID,
7741 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
7742 },
7743
Srinivas Dasari030bad32015-02-18 23:23:54 +05307744
7745 {
7746 .vendor_id = QCA_NL80211_VENDOR_ID,
7747 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
7748 },
7749
Sushant Kaushik084f6592015-09-10 13:11:56 +05307750 {
7751 .vendor_id = QCA_NL80211_VENDOR_ID,
7752 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307753 },
7754 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
7755 .vendor_id = QCA_NL80211_VENDOR_ID,
7756 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
7757 },
Sushant Kaushik084f6592015-09-10 13:11:56 +05307758
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007759};
7760
Jeff Johnson295189b2012-06-20 16:38:30 -07007761/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307762 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307763 * This function is called by hdd_wlan_startup()
7764 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307765 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07007766 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307767struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07007768{
7769 struct wiphy *wiphy;
7770 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307771 /*
7772 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07007773 */
7774 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
7775
7776 if (!wiphy)
7777 {
7778 /* Print error and jump into err label and free the memory */
7779 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
7780 return NULL;
7781 }
7782
Sunil Duttc69bccb2014-05-26 21:30:20 +05307783
Jeff Johnson295189b2012-06-20 16:38:30 -07007784 return wiphy;
7785}
7786
7787/*
7788 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307789 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07007790 * private ioctl to change the band value
7791 */
7792int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
7793{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307794 int i, j;
7795 eNVChannelEnabledType channelEnabledState;
7796
Jeff Johnsone7245742012-09-05 17:12:55 -07007797 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307798
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307799 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007800 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307801
7802 if (NULL == wiphy->bands[i])
7803 {
7804 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
7805 __func__, i);
7806 continue;
7807 }
7808
7809 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
7810 {
7811 struct ieee80211_supported_band *band = wiphy->bands[i];
7812
7813 channelEnabledState = vos_nv_getChannelEnabledState(
7814 band->channels[j].hw_value);
7815
7816 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
7817 {
Abhishek Singh678227a2014-11-04 10:52:38 +05307818 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307819 continue;
7820 }
7821 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
7822 {
7823 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7824 continue;
7825 }
7826
7827 if (NV_CHANNEL_DISABLE == channelEnabledState ||
7828 NV_CHANNEL_INVALID == channelEnabledState)
7829 {
7830 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7831 }
7832 else if (NV_CHANNEL_DFS == channelEnabledState)
7833 {
7834 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
7835 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
7836 }
7837 else
7838 {
7839 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
7840 |IEEE80211_CHAN_RADAR);
7841 }
7842 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007843 }
7844 return 0;
7845}
7846/*
7847 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307848 * This function is called by hdd_wlan_startup()
7849 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07007850 * This function is used to initialize and register wiphy structure.
7851 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307852int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007853 struct wiphy *wiphy,
7854 hdd_config_t *pCfg
7855 )
7856{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307857 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307858 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7859
Jeff Johnsone7245742012-09-05 17:12:55 -07007860 ENTER();
7861
Jeff Johnson295189b2012-06-20 16:38:30 -07007862 /* Now bind the underlying wlan device with wiphy */
7863 set_wiphy_dev(wiphy, dev);
7864
7865 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007866
Kiet Lam6c583332013-10-14 05:37:09 +05307867#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07007868 /* the flag for the other case would be initialzed in
7869 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07007870 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05307871#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007872
Amar Singhalfddc28c2013-09-05 13:03:40 -07007873 /* This will disable updating of NL channels from passive to
7874 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307875#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7876 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
7877#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07007878 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307879#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07007880
Amar Singhala49cbc52013-10-08 18:37:44 -07007881
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007882#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07007883 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
7884 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
7885 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07007886 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307887#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7888 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
7889#else
7890 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
7891#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007892#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007893
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007894#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007895 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08007896#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007897 || pCfg->isFastRoamIniFeatureEnabled
7898#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007899#ifdef FEATURE_WLAN_ESE
7900 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007901#endif
7902 )
7903 {
7904 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
7905 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08007906#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007907#ifdef FEATURE_WLAN_TDLS
7908 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
7909 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
7910#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307911#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05307912 if (pCfg->configPNOScanSupport)
7913 {
7914 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
7915 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
7916 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
7917 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
7918 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307919#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007920
Abhishek Singh10d85972015-04-17 10:27:23 +05307921#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7922 wiphy->features |= NL80211_FEATURE_HT_IBSS;
7923#endif
7924
Amar Singhalfddc28c2013-09-05 13:03:40 -07007925#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007926 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
7927 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07007928 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007929 driver need to determine what to do with both
7930 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07007931
7932 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07007933#else
7934 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007935#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007936
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307937 wiphy->max_scan_ssids = MAX_SCAN_SSID;
7938
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05307939 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07007940
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307941 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
7942
Jeff Johnson295189b2012-06-20 16:38:30 -07007943 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05307944 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
7945 | BIT(NL80211_IFTYPE_ADHOC)
7946 | BIT(NL80211_IFTYPE_P2P_CLIENT)
7947 | BIT(NL80211_IFTYPE_P2P_GO)
7948 | BIT(NL80211_IFTYPE_AP);
7949
7950 if (VOS_MONITOR_MODE == hdd_get_conparam())
7951 {
7952 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
7953 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007954
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307955 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007956 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307957#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7958 if( pCfg->enableMCC )
7959 {
7960 /* Currently, supports up to two channels */
7961 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007962
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307963 if( !pCfg->allowMCCGODiffBI )
7964 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007965
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307966 }
7967 wiphy->iface_combinations = &wlan_hdd_iface_combination;
7968 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007969#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307970 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007971
Jeff Johnson295189b2012-06-20 16:38:30 -07007972 /* Before registering we need to update the ht capabilitied based
7973 * on ini values*/
7974 if( !pCfg->ShortGI20MhzEnable )
7975 {
7976 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
7977 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
7978 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
7979 }
7980
7981 if( !pCfg->ShortGI40MhzEnable )
7982 {
7983 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
7984 }
7985
7986 if( !pCfg->nChannelBondingMode5GHz )
7987 {
7988 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
7989 }
7990
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307991 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307992 if (true == hdd_is_5g_supported(pHddCtx))
7993 {
7994 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
7995 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307996
7997 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
7998 {
7999
8000 if (NULL == wiphy->bands[i])
8001 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05308002 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05308003 __func__, i);
8004 continue;
8005 }
8006
8007 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
8008 {
8009 struct ieee80211_supported_band *band = wiphy->bands[i];
8010
8011 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
8012 {
8013 // Enable social channels for P2P
8014 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
8015 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
8016 else
8017 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8018 continue;
8019 }
8020 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
8021 {
8022 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
8023 continue;
8024 }
8025 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008026 }
8027 /*Initialise the supported cipher suite details*/
8028 wiphy->cipher_suites = hdd_cipher_suites;
8029 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
8030
8031 /*signal strength in mBm (100*dBm) */
8032 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
8033
8034#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05308035 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008036#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008037
Sunil Duttc69bccb2014-05-26 21:30:20 +05308038 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8039 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008040 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8041 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8042
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308043 EXIT();
8044 return 0;
8045}
8046
8047/* In this function we are registering wiphy. */
8048int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8049{
8050 ENTER();
8051 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008052 if (0 > wiphy_register(wiphy))
8053 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308054 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008055 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8056 return -EIO;
8057 }
8058
8059 EXIT();
8060 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308061}
Jeff Johnson295189b2012-06-20 16:38:30 -07008062
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308063/* In this function we are updating channel list when,
8064 regulatory domain is FCC and country code is US.
8065 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8066 As per FCC smart phone is not a indoor device.
8067 GO should not opeate on indoor channels */
8068void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8069{
8070 int j;
8071 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8072 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8073 //Default counrtycode from NV at the time of wiphy initialization.
8074 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8075 &defaultCountryCode[0]))
8076 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008077 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308078 }
8079 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8080 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308081 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8082 {
8083 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8084 return;
8085 }
8086 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8087 {
8088 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8089 // Mark UNII -1 band channel as passive
8090 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8091 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8092 }
8093 }
8094}
8095
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308096/* This function registers for all frame which supplicant is interested in */
8097void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008098{
Jeff Johnson295189b2012-06-20 16:38:30 -07008099 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8100 /* Register for all P2P action, public action etc frames */
8101 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8102
Jeff Johnsone7245742012-09-05 17:12:55 -07008103 ENTER();
8104
Jeff Johnson295189b2012-06-20 16:38:30 -07008105 /* Right now we are registering these frame when driver is getting
8106 initialized. Once we will move to 2.6.37 kernel, in which we have
8107 frame register ops, we will move this code as a part of that */
8108 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308109 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008110 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8111
8112 /* GAS Initial Response */
8113 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8114 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308115
Jeff Johnson295189b2012-06-20 16:38:30 -07008116 /* GAS Comeback Request */
8117 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8118 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8119
8120 /* GAS Comeback Response */
8121 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8122 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8123
8124 /* P2P Public Action */
8125 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308126 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008127 P2P_PUBLIC_ACTION_FRAME_SIZE );
8128
8129 /* P2P Action */
8130 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8131 (v_U8_t*)P2P_ACTION_FRAME,
8132 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008133
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308134 /* WNM BSS Transition Request frame */
8135 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8136 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8137 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008138
8139 /* WNM-Notification */
8140 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8141 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8142 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008143}
8144
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308145void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008146{
Jeff Johnson295189b2012-06-20 16:38:30 -07008147 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8148 /* Register for all P2P action, public action etc frames */
8149 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8150
Jeff Johnsone7245742012-09-05 17:12:55 -07008151 ENTER();
8152
Jeff Johnson295189b2012-06-20 16:38:30 -07008153 /* Right now we are registering these frame when driver is getting
8154 initialized. Once we will move to 2.6.37 kernel, in which we have
8155 frame register ops, we will move this code as a part of that */
8156 /* GAS Initial Request */
8157
8158 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8159 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8160
8161 /* GAS Initial Response */
8162 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8163 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308164
Jeff Johnson295189b2012-06-20 16:38:30 -07008165 /* GAS Comeback Request */
8166 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8167 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8168
8169 /* GAS Comeback Response */
8170 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8171 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8172
8173 /* P2P Public Action */
8174 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308175 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008176 P2P_PUBLIC_ACTION_FRAME_SIZE );
8177
8178 /* P2P Action */
8179 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8180 (v_U8_t*)P2P_ACTION_FRAME,
8181 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008182 /* WNM-Notification */
8183 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8184 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8185 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008186}
8187
8188#ifdef FEATURE_WLAN_WAPI
8189void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308190 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008191{
8192 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8193 tCsrRoamSetKey setKey;
8194 v_BOOL_t isConnected = TRUE;
8195 int status = 0;
8196 v_U32_t roamId= 0xFF;
8197 tANI_U8 *pKeyPtr = NULL;
8198 int n = 0;
8199
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308200 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8201 __func__, hdd_device_modetoString(pAdapter->device_mode),
8202 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008203
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308204 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008205 setKey.keyId = key_index; // Store Key ID
8206 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8207 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8208 setKey.paeRole = 0 ; // the PAE role
8209 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8210 {
8211 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8212 }
8213 else
8214 {
8215 isConnected = hdd_connIsConnected(pHddStaCtx);
8216 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8217 }
8218 setKey.keyLength = key_Len;
8219 pKeyPtr = setKey.Key;
8220 memcpy( pKeyPtr, key, key_Len);
8221
Arif Hussain6d2a3322013-11-17 19:50:10 -08008222 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008223 __func__, key_Len);
8224 for (n = 0 ; n < key_Len; n++)
8225 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8226 __func__,n,setKey.Key[n]);
8227
8228 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8229 if ( isConnected )
8230 {
8231 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8232 pAdapter->sessionId, &setKey, &roamId );
8233 }
8234 if ( status != 0 )
8235 {
8236 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8237 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8238 __LINE__, status );
8239 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8240 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308241 /* Need to clear any trace of key value in the memory.
8242 * Thus zero out the memory even though it is local
8243 * variable.
8244 */
8245 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008246}
8247#endif /* FEATURE_WLAN_WAPI*/
8248
8249#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308250int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008251 beacon_data_t **ppBeacon,
8252 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008253#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308254int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008255 beacon_data_t **ppBeacon,
8256 struct cfg80211_beacon_data *params,
8257 int dtim_period)
8258#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308259{
Jeff Johnson295189b2012-06-20 16:38:30 -07008260 int size;
8261 beacon_data_t *beacon = NULL;
8262 beacon_data_t *old = NULL;
8263 int head_len,tail_len;
8264
Jeff Johnsone7245742012-09-05 17:12:55 -07008265 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008266 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308267 {
8268 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8269 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008270 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308271 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008272
8273 old = pAdapter->sessionCtx.ap.beacon;
8274
8275 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308276 {
8277 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8278 FL("session(%d) old and new heads points to NULL"),
8279 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008280 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308281 }
8282
8283 if (params->tail && !params->tail_len)
8284 {
8285 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8286 FL("tail_len is zero but tail is not NULL"));
8287 return -EINVAL;
8288 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008289
Jeff Johnson295189b2012-06-20 16:38:30 -07008290#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8291 /* Kernel 3.0 is not updating dtim_period for set beacon */
8292 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308293 {
8294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8295 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008296 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308297 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008298#endif
8299
8300 if(params->head)
8301 head_len = params->head_len;
8302 else
8303 head_len = old->head_len;
8304
8305 if(params->tail || !old)
8306 tail_len = params->tail_len;
8307 else
8308 tail_len = old->tail_len;
8309
8310 size = sizeof(beacon_data_t) + head_len + tail_len;
8311
8312 beacon = kzalloc(size, GFP_KERNEL);
8313
8314 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308315 {
8316 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8317 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008318 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308319 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008320
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008321#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008322 if(params->dtim_period || !old )
8323 beacon->dtim_period = params->dtim_period;
8324 else
8325 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008326#else
8327 if(dtim_period || !old )
8328 beacon->dtim_period = dtim_period;
8329 else
8330 beacon->dtim_period = old->dtim_period;
8331#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308332
Jeff Johnson295189b2012-06-20 16:38:30 -07008333 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
8334 beacon->tail = beacon->head + head_len;
8335 beacon->head_len = head_len;
8336 beacon->tail_len = tail_len;
8337
8338 if(params->head) {
8339 memcpy (beacon->head,params->head,beacon->head_len);
8340 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308341 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07008342 if(old)
8343 memcpy (beacon->head,old->head,beacon->head_len);
8344 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308345
Jeff Johnson295189b2012-06-20 16:38:30 -07008346 if(params->tail) {
8347 memcpy (beacon->tail,params->tail,beacon->tail_len);
8348 }
8349 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308350 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07008351 memcpy (beacon->tail,old->tail,beacon->tail_len);
8352 }
8353
8354 *ppBeacon = beacon;
8355
8356 kfree(old);
8357
8358 return 0;
8359
8360}
Jeff Johnson295189b2012-06-20 16:38:30 -07008361
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308362v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
8363#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
8364 const v_U8_t *pIes,
8365#else
8366 v_U8_t *pIes,
8367#endif
8368 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008369{
8370 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308371 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07008372 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308373
Jeff Johnson295189b2012-06-20 16:38:30 -07008374 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308375 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008376 elem_id = ptr[0];
8377 elem_len = ptr[1];
8378 left -= 2;
8379 if(elem_len > left)
8380 {
8381 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008382 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008383 eid,elem_len,left);
8384 return NULL;
8385 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308386 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008387 {
8388 return ptr;
8389 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308390
Jeff Johnson295189b2012-06-20 16:38:30 -07008391 left -= elem_len;
8392 ptr += (elem_len + 2);
8393 }
8394 return NULL;
8395}
8396
Jeff Johnson295189b2012-06-20 16:38:30 -07008397/* Check if rate is 11g rate or not */
8398static int wlan_hdd_rate_is_11g(u8 rate)
8399{
Sanjay Devnani28322e22013-06-21 16:13:40 -07008400 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008401 u8 i;
8402 for (i = 0; i < 8; i++)
8403 {
8404 if(rate == gRateArray[i])
8405 return TRUE;
8406 }
8407 return FALSE;
8408}
8409
8410/* Check for 11g rate and set proper 11g only mode */
8411static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
8412 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
8413{
8414 u8 i, num_rates = pIe[0];
8415
8416 pIe += 1;
8417 for ( i = 0; i < num_rates; i++)
8418 {
8419 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
8420 {
8421 /* If rate set have 11g rate than change the mode to 11G */
8422 *pSapHw_mode = eSAP_DOT11_MODE_11g;
8423 if (pIe[i] & BASIC_RATE_MASK)
8424 {
8425 /* If we have 11g rate as basic rate, it means mode
8426 is 11g only mode.
8427 */
8428 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
8429 *pCheckRatesfor11g = FALSE;
8430 }
8431 }
8432 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
8433 {
8434 *require_ht = TRUE;
8435 }
8436 }
8437 return;
8438}
8439
8440static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
8441{
8442 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
8443 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8444 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
8445 u8 checkRatesfor11g = TRUE;
8446 u8 require_ht = FALSE;
8447 u8 *pIe=NULL;
8448
8449 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
8450
8451 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
8452 pBeacon->head_len, WLAN_EID_SUPP_RATES);
8453 if (pIe != NULL)
8454 {
8455 pIe += 1;
8456 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8457 &pConfig->SapHw_mode);
8458 }
8459
8460 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8461 WLAN_EID_EXT_SUPP_RATES);
8462 if (pIe != NULL)
8463 {
8464
8465 pIe += 1;
8466 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8467 &pConfig->SapHw_mode);
8468 }
8469
8470 if( pConfig->channel > 14 )
8471 {
8472 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
8473 }
8474
8475 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8476 WLAN_EID_HT_CAPABILITY);
8477
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308478 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07008479 {
8480 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
8481 if(require_ht)
8482 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
8483 }
8484}
8485
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308486static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
8487 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
8488{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008489 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308490 v_U8_t *pIe = NULL;
8491 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8492
8493 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
8494 pBeacon->tail, pBeacon->tail_len);
8495
8496 if (pIe)
8497 {
8498 ielen = pIe[1] + 2;
8499 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8500 {
8501 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
8502 }
8503 else
8504 {
8505 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
8506 return -EINVAL;
8507 }
8508 *total_ielen += ielen;
8509 }
8510 return 0;
8511}
8512
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008513static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
8514 v_U8_t *genie, v_U8_t *total_ielen)
8515{
8516 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8517 int left = pBeacon->tail_len;
8518 v_U8_t *ptr = pBeacon->tail;
8519 v_U8_t elem_id, elem_len;
8520 v_U16_t ielen = 0;
8521
8522 if ( NULL == ptr || 0 == left )
8523 return;
8524
8525 while (left >= 2)
8526 {
8527 elem_id = ptr[0];
8528 elem_len = ptr[1];
8529 left -= 2;
8530 if (elem_len > left)
8531 {
8532 hddLog( VOS_TRACE_LEVEL_ERROR,
8533 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
8534 elem_id, elem_len, left);
8535 return;
8536 }
8537 if (IE_EID_VENDOR == elem_id)
8538 {
8539 /* skipping the VSIE's which we don't want to include or
8540 * it will be included by existing code
8541 */
8542 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
8543#ifdef WLAN_FEATURE_WFD
8544 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
8545#endif
8546 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8547 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8548 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
8549 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8550 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
8551 {
8552 ielen = ptr[1] + 2;
8553 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8554 {
8555 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
8556 *total_ielen += ielen;
8557 }
8558 else
8559 {
8560 hddLog( VOS_TRACE_LEVEL_ERROR,
8561 "IE Length is too big "
8562 "IEs eid=%d elem_len=%d total_ie_lent=%d",
8563 elem_id, elem_len, *total_ielen);
8564 }
8565 }
8566 }
8567
8568 left -= elem_len;
8569 ptr += (elem_len + 2);
8570 }
8571 return;
8572}
8573
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008574#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008575static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8576 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008577#else
8578static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8579 struct cfg80211_beacon_data *params)
8580#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008581{
8582 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308583 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008584 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07008585 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008586
8587 genie = vos_mem_malloc(MAX_GENIE_LEN);
8588
8589 if(genie == NULL) {
8590
8591 return -ENOMEM;
8592 }
8593
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308594 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8595 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008596 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308597 hddLog(LOGE,
8598 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308599 ret = -EINVAL;
8600 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008601 }
8602
8603#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308604 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8605 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
8606 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308607 hddLog(LOGE,
8608 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308609 ret = -EINVAL;
8610 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008611 }
8612#endif
8613
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308614 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8615 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008616 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308617 hddLog(LOGE,
8618 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308619 ret = -EINVAL;
8620 goto done;
8621 }
8622
8623 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
8624 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008625 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07008626 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008627
8628 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8629 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
8630 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
8631 {
8632 hddLog(LOGE,
8633 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008634 ret = -EINVAL;
8635 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008636 }
8637
8638 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8639 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
8640 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8641 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8642 ==eHAL_STATUS_FAILURE)
8643 {
8644 hddLog(LOGE,
8645 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008646 ret = -EINVAL;
8647 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008648 }
8649
8650 // Added for ProResp IE
8651 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
8652 {
8653 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
8654 u8 probe_rsp_ie_len[3] = {0};
8655 u8 counter = 0;
8656 /* Check Probe Resp Length if it is greater then 255 then Store
8657 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
8658 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
8659 Store More then 255 bytes into One Variable.
8660 */
8661 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
8662 {
8663 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
8664 {
8665 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
8666 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
8667 }
8668 else
8669 {
8670 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
8671 rem_probe_resp_ie_len = 0;
8672 }
8673 }
8674
8675 rem_probe_resp_ie_len = 0;
8676
8677 if (probe_rsp_ie_len[0] > 0)
8678 {
8679 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8680 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
8681 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8682 probe_rsp_ie_len[0], NULL,
8683 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8684 {
8685 hddLog(LOGE,
8686 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008687 ret = -EINVAL;
8688 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008689 }
8690 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
8691 }
8692
8693 if (probe_rsp_ie_len[1] > 0)
8694 {
8695 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8696 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
8697 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8698 probe_rsp_ie_len[1], NULL,
8699 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8700 {
8701 hddLog(LOGE,
8702 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008703 ret = -EINVAL;
8704 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008705 }
8706 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
8707 }
8708
8709 if (probe_rsp_ie_len[2] > 0)
8710 {
8711 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8712 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
8713 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8714 probe_rsp_ie_len[2], NULL,
8715 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8716 {
8717 hddLog(LOGE,
8718 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008719 ret = -EINVAL;
8720 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008721 }
8722 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
8723 }
8724
8725 if (probe_rsp_ie_len[1] == 0 )
8726 {
8727 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8728 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8729 eANI_BOOLEAN_FALSE) )
8730 {
8731 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008732 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008733 }
8734 }
8735
8736 if (probe_rsp_ie_len[2] == 0 )
8737 {
8738 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8739 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8740 eANI_BOOLEAN_FALSE) )
8741 {
8742 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008743 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008744 }
8745 }
8746
8747 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8748 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
8749 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8750 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8751 == eHAL_STATUS_FAILURE)
8752 {
8753 hddLog(LOGE,
8754 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008755 ret = -EINVAL;
8756 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008757 }
8758 }
8759 else
8760 {
8761 // Reset WNI_CFG_PROBE_RSP Flags
8762 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
8763
8764 hddLog(VOS_TRACE_LEVEL_INFO,
8765 "%s: No Probe Response IE received in set beacon",
8766 __func__);
8767 }
8768
8769 // Added for AssocResp IE
8770 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
8771 {
8772 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8773 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
8774 params->assocresp_ies_len, NULL,
8775 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8776 {
8777 hddLog(LOGE,
8778 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008779 ret = -EINVAL;
8780 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008781 }
8782
8783 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8784 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
8785 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8786 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8787 == eHAL_STATUS_FAILURE)
8788 {
8789 hddLog(LOGE,
8790 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008791 ret = -EINVAL;
8792 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008793 }
8794 }
8795 else
8796 {
8797 hddLog(VOS_TRACE_LEVEL_INFO,
8798 "%s: No Assoc Response IE received in set beacon",
8799 __func__);
8800
8801 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8802 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8803 eANI_BOOLEAN_FALSE) )
8804 {
8805 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008806 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008807 }
8808 }
8809
Jeff Johnsone7245742012-09-05 17:12:55 -07008810done:
Jeff Johnson295189b2012-06-20 16:38:30 -07008811 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308812 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008813}
Jeff Johnson295189b2012-06-20 16:38:30 -07008814
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308815/*
Jeff Johnson295189b2012-06-20 16:38:30 -07008816 * FUNCTION: wlan_hdd_validate_operation_channel
8817 * called by wlan_hdd_cfg80211_start_bss() and
8818 * wlan_hdd_cfg80211_set_channel()
8819 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308820 * channel list.
8821 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07008822VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008823{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308824
Jeff Johnson295189b2012-06-20 16:38:30 -07008825 v_U32_t num_ch = 0;
8826 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8827 u32 indx = 0;
8828 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308829 v_U8_t fValidChannel = FALSE, count = 0;
8830 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308831
Jeff Johnson295189b2012-06-20 16:38:30 -07008832 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8833
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308834 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008835 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308836 /* Validate the channel */
8837 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008838 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308839 if ( channel == rfChannels[count].channelNum )
8840 {
8841 fValidChannel = TRUE;
8842 break;
8843 }
8844 }
8845 if (fValidChannel != TRUE)
8846 {
8847 hddLog(VOS_TRACE_LEVEL_ERROR,
8848 "%s: Invalid Channel [%d]", __func__, channel);
8849 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008850 }
8851 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308852 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008853 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308854 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8855 valid_ch, &num_ch))
8856 {
8857 hddLog(VOS_TRACE_LEVEL_ERROR,
8858 "%s: failed to get valid channel list", __func__);
8859 return VOS_STATUS_E_FAILURE;
8860 }
8861 for (indx = 0; indx < num_ch; indx++)
8862 {
8863 if (channel == valid_ch[indx])
8864 {
8865 break;
8866 }
8867 }
8868
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308869 if (indx >= num_ch)
8870 {
8871 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
8872 {
8873 eCsrBand band;
8874 unsigned int freq;
8875
8876 sme_GetFreqBand(hHal, &band);
8877
8878 if (eCSR_BAND_5G == band)
8879 {
8880#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8881 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8882 {
8883 freq = ieee80211_channel_to_frequency(channel,
8884 IEEE80211_BAND_2GHZ);
8885 }
8886 else
8887 {
8888 freq = ieee80211_channel_to_frequency(channel,
8889 IEEE80211_BAND_5GHZ);
8890 }
8891#else
8892 freq = ieee80211_channel_to_frequency(channel);
8893#endif
8894 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
8895 return VOS_STATUS_SUCCESS;
8896 }
8897 }
8898
8899 hddLog(VOS_TRACE_LEVEL_ERROR,
8900 "%s: Invalid Channel [%d]", __func__, channel);
8901 return VOS_STATUS_E_FAILURE;
8902 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008903 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308904
Jeff Johnson295189b2012-06-20 16:38:30 -07008905 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308906
Jeff Johnson295189b2012-06-20 16:38:30 -07008907}
8908
Viral Modi3a32cc52013-02-08 11:14:52 -08008909/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308910 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08008911 * This function is used to set the channel number
8912 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308913static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08008914 struct ieee80211_channel *chan,
8915 enum nl80211_channel_type channel_type
8916 )
8917{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308918 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08008919 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07008920 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08008921 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308922 hdd_context_t *pHddCtx;
8923 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08008924
8925 ENTER();
8926
8927 if( NULL == dev )
8928 {
8929 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008930 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08008931 return -ENODEV;
8932 }
8933 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308934
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308935 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8936 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
8937 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08008938 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308939 "%s: device_mode = %s (%d) freq = %d", __func__,
8940 hdd_device_modetoString(pAdapter->device_mode),
8941 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308942
8943 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8944 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308945 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08008946 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308947 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08008948 }
8949
8950 /*
8951 * Do freq to chan conversion
8952 * TODO: for 11a
8953 */
8954
8955 channel = ieee80211_frequency_to_channel(freq);
8956
8957 /* Check freq range */
8958 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
8959 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
8960 {
8961 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008962 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08008963 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
8964 WNI_CFG_CURRENT_CHANNEL_STAMAX);
8965 return -EINVAL;
8966 }
8967
8968 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8969
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05308970 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
8971 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08008972 {
8973 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
8974 {
8975 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008976 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08008977 return -EINVAL;
8978 }
8979 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8980 "%s: set channel to [%d] for device mode =%d",
8981 __func__, channel,pAdapter->device_mode);
8982 }
8983 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08008984 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08008985 )
8986 {
8987 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8988 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
8989 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8990
8991 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
8992 {
8993 /* Link is up then return cant set channel*/
8994 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008995 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08008996 return -EINVAL;
8997 }
8998
8999 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
9000 pHddStaCtx->conn_info.operationChannel = channel;
9001 pRoamProfile->ChannelInfo.ChannelList =
9002 &pHddStaCtx->conn_info.operationChannel;
9003 }
9004 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08009005 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08009006 )
9007 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309008 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
9009 {
9010 if(VOS_STATUS_SUCCESS !=
9011 wlan_hdd_validate_operation_channel(pAdapter,channel))
9012 {
9013 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009014 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309015 return -EINVAL;
9016 }
9017 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9018 }
9019 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08009020 {
9021 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
9022
9023 /* If auto channel selection is configured as enable/ 1 then ignore
9024 channel set by supplicant
9025 */
9026 if ( cfg_param->apAutoChannelSelection )
9027 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309028 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
9029 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08009030 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309031 "%s: set channel to auto channel (0) for device mode =%s (%d)",
9032 __func__, hdd_device_modetoString(pAdapter->device_mode),
9033 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08009034 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309035 else
9036 {
9037 if(VOS_STATUS_SUCCESS !=
9038 wlan_hdd_validate_operation_channel(pAdapter,channel))
9039 {
9040 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009041 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309042 return -EINVAL;
9043 }
9044 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9045 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009046 }
9047 }
9048 else
9049 {
9050 hddLog(VOS_TRACE_LEVEL_FATAL,
9051 "%s: Invalid device mode failed to set valid channel", __func__);
9052 return -EINVAL;
9053 }
9054 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309055 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009056}
9057
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309058static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9059 struct net_device *dev,
9060 struct ieee80211_channel *chan,
9061 enum nl80211_channel_type channel_type
9062 )
9063{
9064 int ret;
9065
9066 vos_ssr_protect(__func__);
9067 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9068 vos_ssr_unprotect(__func__);
9069
9070 return ret;
9071}
9072
Jeff Johnson295189b2012-06-20 16:38:30 -07009073#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9074static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9075 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009076#else
9077static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9078 struct cfg80211_beacon_data *params,
9079 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309080 enum nl80211_hidden_ssid hidden_ssid,
9081 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009082#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009083{
9084 tsap_Config_t *pConfig;
9085 beacon_data_t *pBeacon = NULL;
9086 struct ieee80211_mgmt *pMgmt_frame;
9087 v_U8_t *pIe=NULL;
9088 v_U16_t capab_info;
9089 eCsrAuthType RSNAuthType;
9090 eCsrEncryptionType RSNEncryptType;
9091 eCsrEncryptionType mcRSNEncryptType;
9092 int status = VOS_STATUS_SUCCESS;
9093 tpWLAN_SAPEventCB pSapEventCallback;
9094 hdd_hostapd_state_t *pHostapdState;
9095 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
9096 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309097 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009098 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309099 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009100 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009101 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309102 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009103 v_BOOL_t MFPCapable = VOS_FALSE;
9104 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309105 v_BOOL_t sapEnable11AC =
9106 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07009107 ENTER();
9108
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309109 iniConfig = pHddCtx->cfg_ini;
9110
Jeff Johnson295189b2012-06-20 16:38:30 -07009111 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9112
9113 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9114
9115 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9116
9117 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9118
9119 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9120
9121 //channel is already set in the set_channel Call back
9122 //pConfig->channel = pCommitConfig->channel;
9123
9124 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309125 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009126 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9127
9128 pConfig->dtim_period = pBeacon->dtim_period;
9129
Arif Hussain6d2a3322013-11-17 19:50:10 -08009130 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009131 pConfig->dtim_period);
9132
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009133 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009134 {
9135 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009136 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309137 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9138 {
9139 tANI_BOOLEAN restartNeeded;
9140 pConfig->ieee80211d = 1;
9141 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9142 sme_setRegInfo(hHal, pConfig->countryCode);
9143 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9144 }
9145 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009146 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009147 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009148 pConfig->ieee80211d = 1;
9149 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9150 sme_setRegInfo(hHal, pConfig->countryCode);
9151 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009152 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009153 else
9154 {
9155 pConfig->ieee80211d = 0;
9156 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309157 /*
9158 * If auto channel is configured i.e. channel is 0,
9159 * so skip channel validation.
9160 */
9161 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9162 {
9163 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9164 {
9165 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009166 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309167 return -EINVAL;
9168 }
9169 }
9170 else
9171 {
9172 if(1 != pHddCtx->is_dynamic_channel_range_set)
9173 {
9174 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9175 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9176 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9177 }
9178 pHddCtx->is_dynamic_channel_range_set = 0;
9179 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009180 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009181 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009182 {
9183 pConfig->ieee80211d = 0;
9184 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309185
9186#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9187 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9188 pConfig->authType = eSAP_OPEN_SYSTEM;
9189 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9190 pConfig->authType = eSAP_SHARED_KEY;
9191 else
9192 pConfig->authType = eSAP_AUTO_SWITCH;
9193#else
9194 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9195 pConfig->authType = eSAP_OPEN_SYSTEM;
9196 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9197 pConfig->authType = eSAP_SHARED_KEY;
9198 else
9199 pConfig->authType = eSAP_AUTO_SWITCH;
9200#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009201
9202 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309203
9204 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07009205 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
9206
9207 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
9208
9209 /*Set wps station to configured*/
9210 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
9211
9212 if(pIe)
9213 {
9214 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
9215 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009216 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07009217 return -EINVAL;
9218 }
9219 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
9220 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009221 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07009222 /* Check 15 bit of WPS IE as it contain information for wps state
9223 * WPS state
9224 */
9225 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
9226 {
9227 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
9228 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
9229 {
9230 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
9231 }
9232 }
9233 }
9234 else
9235 {
9236 pConfig->wps_state = SAP_WPS_DISABLED;
9237 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309238 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07009239
c_hpothufe599e92014-06-16 11:38:55 +05309240 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9241 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9242 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
9243 eCSR_ENCRYPT_TYPE_NONE;
9244
Jeff Johnson295189b2012-06-20 16:38:30 -07009245 pConfig->RSNWPAReqIELength = 0;
9246 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309247 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009248 WLAN_EID_RSN);
9249 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309250 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009251 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9252 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9253 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309254 /* The actual processing may eventually be more extensive than
9255 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07009256 * by the app.
9257 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309258 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009259 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9260 &RSNEncryptType,
9261 &mcRSNEncryptType,
9262 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009263 &MFPCapable,
9264 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009265 pConfig->pRSNWPAReqIE[1]+2,
9266 pConfig->pRSNWPAReqIE );
9267
9268 if( VOS_STATUS_SUCCESS == status )
9269 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309270 /* Now copy over all the security attributes you have
9271 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009272 * */
9273 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9274 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9275 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9276 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309277 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009278 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009279 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9280 }
9281 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309282
Jeff Johnson295189b2012-06-20 16:38:30 -07009283 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9284 pBeacon->tail, pBeacon->tail_len);
9285
9286 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
9287 {
9288 if (pConfig->pRSNWPAReqIE)
9289 {
9290 /*Mixed mode WPA/WPA2*/
9291 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
9292 pConfig->RSNWPAReqIELength += pIe[1] + 2;
9293 }
9294 else
9295 {
9296 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9297 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9298 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309299 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009300 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9301 &RSNEncryptType,
9302 &mcRSNEncryptType,
9303 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009304 &MFPCapable,
9305 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009306 pConfig->pRSNWPAReqIE[1]+2,
9307 pConfig->pRSNWPAReqIE );
9308
9309 if( VOS_STATUS_SUCCESS == status )
9310 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309311 /* Now copy over all the security attributes you have
9312 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009313 * */
9314 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9315 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9316 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9317 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309318 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009319 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009320 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9321 }
9322 }
9323 }
9324
Jeff Johnson4416a782013-03-25 14:17:50 -07009325 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
9326 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
9327 return -EINVAL;
9328 }
9329
Jeff Johnson295189b2012-06-20 16:38:30 -07009330 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
9331
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009332#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009333 if (params->ssid != NULL)
9334 {
9335 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
9336 pConfig->SSIDinfo.ssid.length = params->ssid_len;
9337 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9338 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9339 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009340#else
9341 if (ssid != NULL)
9342 {
9343 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
9344 pConfig->SSIDinfo.ssid.length = ssid_len;
9345 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9346 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9347 }
9348#endif
9349
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309350 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07009351 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309352
Jeff Johnson295189b2012-06-20 16:38:30 -07009353 /* default value */
9354 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9355 pConfig->num_accept_mac = 0;
9356 pConfig->num_deny_mac = 0;
9357
9358 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9359 pBeacon->tail, pBeacon->tail_len);
9360
9361 /* pIe for black list is following form:
9362 type : 1 byte
9363 length : 1 byte
9364 OUI : 4 bytes
9365 acl type : 1 byte
9366 no of mac addr in black list: 1 byte
9367 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309368 */
9369 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009370 {
9371 pConfig->SapMacaddr_acl = pIe[6];
9372 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009373 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009374 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309375 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
9376 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009377 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9378 for (i = 0; i < pConfig->num_deny_mac; i++)
9379 {
9380 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9381 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309382 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009383 }
9384 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9385 pBeacon->tail, pBeacon->tail_len);
9386
9387 /* pIe for white list is following form:
9388 type : 1 byte
9389 length : 1 byte
9390 OUI : 4 bytes
9391 acl type : 1 byte
9392 no of mac addr in white list: 1 byte
9393 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309394 */
9395 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009396 {
9397 pConfig->SapMacaddr_acl = pIe[6];
9398 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009399 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009400 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309401 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
9402 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009403 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9404 for (i = 0; i < pConfig->num_accept_mac; i++)
9405 {
9406 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9407 acl_entry++;
9408 }
9409 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309410
Jeff Johnson295189b2012-06-20 16:38:30 -07009411 wlan_hdd_set_sapHwmode(pHostapdAdapter);
9412
Jeff Johnsone7245742012-09-05 17:12:55 -07009413#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009414 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309415 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
9416 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05309417 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
9418 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009419 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
9420 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309421 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
9422 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07009423 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309424 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07009425 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309426 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009427
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309428 /* If ACS disable and selected channel <= 14
9429 * OR
9430 * ACS enabled and ACS operating band is choosen as 2.4
9431 * AND
9432 * VHT in 2.4G Disabled
9433 * THEN
9434 * Fallback to 11N mode
9435 */
9436 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
9437 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05309438 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309439 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009440 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309441 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
9442 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009443 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
9444 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009445 }
9446#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309447
Jeff Johnson295189b2012-06-20 16:38:30 -07009448 // ht_capab is not what the name conveys,this is used for protection bitmap
9449 pConfig->ht_capab =
9450 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
9451
9452 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
9453 {
9454 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
9455 return -EINVAL;
9456 }
9457
9458 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309459 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07009460 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
9461 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309462 pConfig->obssProtEnabled =
9463 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07009464
Chet Lanctot8cecea22014-02-11 19:09:36 -08009465#ifdef WLAN_FEATURE_11W
9466 pConfig->mfpCapable = MFPCapable;
9467 pConfig->mfpRequired = MFPRequired;
9468 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
9469 pConfig->mfpCapable, pConfig->mfpRequired);
9470#endif
9471
Arif Hussain6d2a3322013-11-17 19:50:10 -08009472 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07009473 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08009474 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
9475 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
9476 (int)pConfig->channel);
9477 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
9478 pConfig->SapHw_mode, pConfig->privacy,
9479 pConfig->authType);
9480 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
9481 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
9482 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
9483 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07009484
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309485 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009486 {
9487 //Bss already started. just return.
9488 //TODO Probably it should update some beacon params.
9489 hddLog( LOGE, "Bss Already started...Ignore the request");
9490 EXIT();
9491 return 0;
9492 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309493
Agarwal Ashish51325b52014-06-16 16:50:49 +05309494 if (vos_max_concurrent_connections_reached()) {
9495 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9496 return -EINVAL;
9497 }
9498
Jeff Johnson295189b2012-06-20 16:38:30 -07009499 pConfig->persona = pHostapdAdapter->device_mode;
9500
Peng Xu2446a892014-09-05 17:21:18 +05309501 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
9502 if ( NULL != psmeConfig)
9503 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309504 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05309505 sme_GetConfigParam(hHal, psmeConfig);
9506 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309507#ifdef WLAN_FEATURE_AP_HT40_24G
9508 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
9509 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
9510 && pHddCtx->cfg_ini->apHT40_24GEnabled)
9511 {
9512 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
9513 sme_UpdateConfig (hHal, psmeConfig);
9514 }
9515#endif
Peng Xu2446a892014-09-05 17:21:18 +05309516 vos_mem_free(psmeConfig);
9517 }
Peng Xuafc34e32014-09-25 13:23:55 +05309518 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05309519
Jeff Johnson295189b2012-06-20 16:38:30 -07009520 pSapEventCallback = hdd_hostapd_SAPEventCB;
9521 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
9522 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
9523 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009524 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009525 return -EINVAL;
9526 }
9527
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309528 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07009529 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
9530
9531 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309532
Jeff Johnson295189b2012-06-20 16:38:30 -07009533 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309534 {
9535 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009536 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07009537 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009538 VOS_ASSERT(0);
9539 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309540
Jeff Johnson295189b2012-06-20 16:38:30 -07009541 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05309542 /* Initialize WMM configuation */
9543 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309544 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009545
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009546#ifdef WLAN_FEATURE_P2P_DEBUG
9547 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
9548 {
9549 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
9550 {
9551 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9552 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009553 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009554 }
9555 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
9556 {
9557 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9558 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009559 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009560 }
9561 }
9562#endif
9563
Jeff Johnson295189b2012-06-20 16:38:30 -07009564 pHostapdState->bCommit = TRUE;
9565 EXIT();
9566
9567 return 0;
9568}
9569
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009570#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309571static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309572 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009573 struct beacon_parameters *params)
9574{
9575 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309576 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309577 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009578
9579 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309580
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309581 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9582 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
9583 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309584 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
9585 hdd_device_modetoString(pAdapter->device_mode),
9586 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009587
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309588 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9589 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309590 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009591 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309592 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009593 }
9594
Agarwal Ashish51325b52014-06-16 16:50:49 +05309595 if (vos_max_concurrent_connections_reached()) {
9596 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9597 return -EINVAL;
9598 }
9599
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309600 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009601 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009602 )
9603 {
9604 beacon_data_t *old,*new;
9605
9606 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309607
Jeff Johnson295189b2012-06-20 16:38:30 -07009608 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309609 {
9610 hddLog(VOS_TRACE_LEVEL_WARN,
9611 FL("already beacon info added to session(%d)"),
9612 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009613 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309614 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009615
9616 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9617
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309618 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07009619 {
9620 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009621 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009622 return -EINVAL;
9623 }
9624
9625 pAdapter->sessionCtx.ap.beacon = new;
9626
9627 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9628 }
9629
9630 EXIT();
9631 return status;
9632}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309633
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309634static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
9635 struct net_device *dev,
9636 struct beacon_parameters *params)
9637{
9638 int ret;
9639
9640 vos_ssr_protect(__func__);
9641 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
9642 vos_ssr_unprotect(__func__);
9643
9644 return ret;
9645}
9646
9647static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009648 struct net_device *dev,
9649 struct beacon_parameters *params)
9650{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309651 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309652 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9653 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309654 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009655
9656 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309657
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309658 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9659 TRACE_CODE_HDD_CFG80211_SET_BEACON,
9660 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
9661 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9662 __func__, hdd_device_modetoString(pAdapter->device_mode),
9663 pAdapter->device_mode);
9664
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309665 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9666 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309667 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009668 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309669 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009670 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309671
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309672 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009673 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309674 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009675 {
9676 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309677
Jeff Johnson295189b2012-06-20 16:38:30 -07009678 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309679
Jeff Johnson295189b2012-06-20 16:38:30 -07009680 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309681 {
9682 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9683 FL("session(%d) old and new heads points to NULL"),
9684 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009685 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309686 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009687
9688 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9689
9690 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309691 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009692 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009693 return -EINVAL;
9694 }
9695
9696 pAdapter->sessionCtx.ap.beacon = new;
9697
9698 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9699 }
9700
9701 EXIT();
9702 return status;
9703}
9704
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309705static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
9706 struct net_device *dev,
9707 struct beacon_parameters *params)
9708{
9709 int ret;
9710
9711 vos_ssr_protect(__func__);
9712 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
9713 vos_ssr_unprotect(__func__);
9714
9715 return ret;
9716}
9717
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009718#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9719
9720#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309721static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009722 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009723#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309724static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009725 struct net_device *dev)
9726#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009727{
9728 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07009729 hdd_context_t *pHddCtx = NULL;
9730 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309731 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309732 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009733
9734 ENTER();
9735
9736 if (NULL == pAdapter)
9737 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309738 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009739 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009740 return -ENODEV;
9741 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009742
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309743 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9744 TRACE_CODE_HDD_CFG80211_STOP_AP,
9745 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309746 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9747 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309748 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009749 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309750 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07009751 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009752
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009753 pScanInfo = &pHddCtx->scan_info;
9754
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309755 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9756 __func__, hdd_device_modetoString(pAdapter->device_mode),
9757 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009758
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309759 ret = wlan_hdd_scan_abort(pAdapter);
9760
Girish Gowli4bf7a632014-06-12 13:42:11 +05309761 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07009762 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309763 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9764 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309765
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309766 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07009767 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309768 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9769 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08009770
Jeff Johnsone7245742012-09-05 17:12:55 -07009771 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309772 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07009773 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309774 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009775 }
9776
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05309777 /* Delete all associated STAs before stopping AP/P2P GO */
9778 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05309779 hdd_hostapd_stop(dev);
9780
Jeff Johnson295189b2012-06-20 16:38:30 -07009781 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009782 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009783 )
9784 {
9785 beacon_data_t *old;
9786
9787 old = pAdapter->sessionCtx.ap.beacon;
9788
9789 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309790 {
9791 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9792 FL("session(%d) beacon data points to NULL"),
9793 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009794 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309795 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009796
Jeff Johnson295189b2012-06-20 16:38:30 -07009797 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009798
9799 mutex_lock(&pHddCtx->sap_lock);
9800 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9801 {
Jeff Johnson4416a782013-03-25 14:17:50 -07009802 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009803 {
9804 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9805
9806 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
9807
9808 if (!VOS_IS_STATUS_SUCCESS(status))
9809 {
9810 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009811 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009812 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309813 }
9814 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009815 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309816 /* BSS stopped, clear the active sessions for this device mode */
9817 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009818 }
9819 mutex_unlock(&pHddCtx->sap_lock);
9820
9821 if(status != VOS_STATUS_SUCCESS)
9822 {
9823 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009824 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009825 return -EINVAL;
9826 }
9827
Jeff Johnson4416a782013-03-25 14:17:50 -07009828 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009829 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
9830 ==eHAL_STATUS_FAILURE)
9831 {
9832 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009833 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009834 }
9835
Jeff Johnson4416a782013-03-25 14:17:50 -07009836 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009837 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9838 eANI_BOOLEAN_FALSE) )
9839 {
9840 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009841 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009842 }
9843
9844 // Reset WNI_CFG_PROBE_RSP Flags
9845 wlan_hdd_reset_prob_rspies(pAdapter);
9846
9847 pAdapter->sessionCtx.ap.beacon = NULL;
9848 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009849#ifdef WLAN_FEATURE_P2P_DEBUG
9850 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
9851 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
9852 {
9853 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
9854 "GO got removed");
9855 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
9856 }
9857#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009858 }
9859 EXIT();
9860 return status;
9861}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009862
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309863#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9864static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
9865 struct net_device *dev)
9866{
9867 int ret;
9868
9869 vos_ssr_protect(__func__);
9870 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
9871 vos_ssr_unprotect(__func__);
9872
9873 return ret;
9874}
9875#else
9876static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
9877 struct net_device *dev)
9878{
9879 int ret;
9880
9881 vos_ssr_protect(__func__);
9882 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
9883 vos_ssr_unprotect(__func__);
9884
9885 return ret;
9886}
9887#endif
9888
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009889#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
9890
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309891static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309892 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009893 struct cfg80211_ap_settings *params)
9894{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309895 hdd_adapter_t *pAdapter;
9896 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309897 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009898
9899 ENTER();
9900
Girish Gowlib143d7a2015-02-18 19:39:55 +05309901 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07009902 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309903 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05309904 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309905 return -ENODEV;
9906 }
9907
9908 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9909 if (NULL == pAdapter)
9910 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309911 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309912 "%s: HDD adapter is Null", __func__);
9913 return -ENODEV;
9914 }
9915
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309916 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9917 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
9918 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309919 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
9920 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309921 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309922 "%s: HDD adapter magic is invalid", __func__);
9923 return -ENODEV;
9924 }
9925
9926 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309927 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309928 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309929 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309930 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309931 }
9932
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309933 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
9934 __func__, hdd_device_modetoString(pAdapter->device_mode),
9935 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309936
9937 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009938 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009939 )
9940 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309941 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009942
9943 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309944
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009945 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309946 {
9947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9948 FL("already beacon info added to session(%d)"),
9949 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009950 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309951 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009952
Girish Gowlib143d7a2015-02-18 19:39:55 +05309953#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9954 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
9955 &new,
9956 &params->beacon);
9957#else
9958 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
9959 &new,
9960 &params->beacon,
9961 params->dtim_period);
9962#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009963
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309964 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009965 {
9966 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309967 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009968 return -EINVAL;
9969 }
9970 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08009971#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07009972 wlan_hdd_cfg80211_set_channel(wiphy, dev,
9973#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
9974 params->channel, params->channel_type);
9975#else
9976 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
9977#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08009978#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009979 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309980 params->ssid_len, params->hidden_ssid,
9981 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009982 }
9983
9984 EXIT();
9985 return status;
9986}
9987
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309988static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
9989 struct net_device *dev,
9990 struct cfg80211_ap_settings *params)
9991{
9992 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009993
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309994 vos_ssr_protect(__func__);
9995 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
9996 vos_ssr_unprotect(__func__);
9997
9998 return ret;
9999}
10000
10001static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010002 struct net_device *dev,
10003 struct cfg80211_beacon_data *params)
10004{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010005 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010006 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010007 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010008
10009 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010010
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010011 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10012 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
10013 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -080010014 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010015 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010016
10017 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10018 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010019 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010020 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010021 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -070010022 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010023
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010024 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010025 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010026 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010027 {
10028 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010029
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010030 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010031
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010032 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010033 {
10034 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10035 FL("session(%d) beacon data points to NULL"),
10036 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010037 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010038 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010039
10040 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10041
10042 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010043 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010044 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010045 return -EINVAL;
10046 }
10047
10048 pAdapter->sessionCtx.ap.beacon = new;
10049
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010050 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10051 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010052 }
10053
10054 EXIT();
10055 return status;
10056}
10057
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010058static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
10059 struct net_device *dev,
10060 struct cfg80211_beacon_data *params)
10061{
10062 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010063
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010064 vos_ssr_protect(__func__);
10065 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
10066 vos_ssr_unprotect(__func__);
10067
10068 return ret;
10069}
10070
10071#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010072
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010073static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010074 struct net_device *dev,
10075 struct bss_parameters *params)
10076{
10077 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010078 hdd_context_t *pHddCtx;
10079 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010080
10081 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010082
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010083 if (NULL == pAdapter)
10084 {
10085 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10086 "%s: HDD adapter is Null", __func__);
10087 return -ENODEV;
10088 }
10089 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010090 ret = wlan_hdd_validate_context(pHddCtx);
10091 if (0 != ret)
10092 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010093 return ret;
10094 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010095 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10096 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
10097 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010098 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10099 __func__, hdd_device_modetoString(pAdapter->device_mode),
10100 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010101
10102 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010103 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010104 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010105 {
10106 /* ap_isolate == -1 means that in change bss, upper layer doesn't
10107 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010108 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070010109 {
10110 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010111 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010112 }
10113
10114 EXIT();
10115 return 0;
10116}
10117
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010118static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
10119 struct net_device *dev,
10120 struct bss_parameters *params)
10121{
10122 int ret;
10123
10124 vos_ssr_protect(__func__);
10125 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
10126 vos_ssr_unprotect(__func__);
10127
10128 return ret;
10129}
Kiet Lam10841362013-11-01 11:36:50 +053010130/* FUNCTION: wlan_hdd_change_country_code_cd
10131* to wait for contry code completion
10132*/
10133void* wlan_hdd_change_country_code_cb(void *pAdapter)
10134{
10135 hdd_adapter_t *call_back_pAdapter = pAdapter;
10136 complete(&call_back_pAdapter->change_country_code);
10137 return NULL;
10138}
10139
Jeff Johnson295189b2012-06-20 16:38:30 -070010140/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010141 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070010142 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
10143 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010144int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010145 struct net_device *ndev,
10146 enum nl80211_iftype type,
10147 u32 *flags,
10148 struct vif_params *params
10149 )
10150{
10151 struct wireless_dev *wdev;
10152 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010153 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070010154 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010155 tCsrRoamProfile *pRoamProfile = NULL;
10156 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010157 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010158 eMib_dot11DesiredBssType connectedBssType;
10159 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010160 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010161
10162 ENTER();
10163
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010164 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010165 {
10166 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10167 "%s: Adapter context is null", __func__);
10168 return VOS_STATUS_E_FAILURE;
10169 }
10170
10171 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10172 if (!pHddCtx)
10173 {
10174 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10175 "%s: HDD context is null", __func__);
10176 return VOS_STATUS_E_FAILURE;
10177 }
10178
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010179 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10180 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
10181 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010182 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010183 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010184 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010185 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010186 }
10187
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010188 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10189 __func__, hdd_device_modetoString(pAdapter->device_mode),
10190 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010191
Agarwal Ashish51325b52014-06-16 16:50:49 +053010192 if (vos_max_concurrent_connections_reached()) {
10193 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10194 return -EINVAL;
10195 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010196 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070010197 wdev = ndev->ieee80211_ptr;
10198
10199#ifdef WLAN_BTAMP_FEATURE
10200 if((NL80211_IFTYPE_P2P_CLIENT == type)||
10201 (NL80211_IFTYPE_ADHOC == type)||
10202 (NL80211_IFTYPE_AP == type)||
10203 (NL80211_IFTYPE_P2P_GO == type))
10204 {
10205 pHddCtx->isAmpAllowed = VOS_FALSE;
10206 // stop AMP traffic
10207 status = WLANBAP_StopAmp();
10208 if(VOS_STATUS_SUCCESS != status )
10209 {
10210 pHddCtx->isAmpAllowed = VOS_TRUE;
10211 hddLog(VOS_TRACE_LEVEL_FATAL,
10212 "%s: Failed to stop AMP", __func__);
10213 return -EINVAL;
10214 }
10215 }
10216#endif //WLAN_BTAMP_FEATURE
10217 /* Reset the current device mode bit mask*/
10218 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10219
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053010220 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
10221 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
10222 (type == NL80211_IFTYPE_P2P_GO)))
10223 {
10224 /* Notify Mode change in case of concurrency.
10225 * Below function invokes TDLS teardown Functionality Since TDLS is
10226 * not Supported in case of concurrency i.e Once P2P session
10227 * is detected disable offchannel and teardown TDLS links
10228 */
10229 hddLog(LOG1,
10230 FL("Device mode = %d Interface type = %d"),
10231 pAdapter->device_mode, type);
10232 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
10233 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053010234
Jeff Johnson295189b2012-06-20 16:38:30 -070010235 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010236 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070010237 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010238 )
10239 {
10240 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010241 if (!pWextState)
10242 {
10243 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10244 "%s: pWextState is null", __func__);
10245 return VOS_STATUS_E_FAILURE;
10246 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010247 pRoamProfile = &pWextState->roamProfile;
10248 LastBSSType = pRoamProfile->BSSType;
10249
10250 switch (type)
10251 {
10252 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010253 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010254 hddLog(VOS_TRACE_LEVEL_INFO,
10255 "%s: setting interface Type to INFRASTRUCTURE", __func__);
10256 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010257#ifdef WLAN_FEATURE_11AC
10258 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
10259 {
10260 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
10261 }
10262#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010263 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070010264 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010265 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010266 //Check for sub-string p2p to confirm its a p2p interface
10267 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010268 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053010269#ifdef FEATURE_WLAN_TDLS
10270 mutex_lock(&pHddCtx->tdls_lock);
10271 wlan_hdd_tdls_exit(pAdapter, TRUE);
10272 mutex_unlock(&pHddCtx->tdls_lock);
10273#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010274 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10275 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10276 }
10277 else
10278 {
10279 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010280 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010281 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010282 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053010283
Jeff Johnson295189b2012-06-20 16:38:30 -070010284 case NL80211_IFTYPE_ADHOC:
10285 hddLog(VOS_TRACE_LEVEL_INFO,
10286 "%s: setting interface Type to ADHOC", __func__);
10287 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
10288 pRoamProfile->phyMode =
10289 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070010290 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010291 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053010292 hdd_set_ibss_ops( pAdapter );
10293 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053010294
10295 status = hdd_sta_id_hash_attach(pAdapter);
10296 if (VOS_STATUS_SUCCESS != status) {
10297 hddLog(VOS_TRACE_LEVEL_ERROR,
10298 FL("Failed to initialize hash for IBSS"));
10299 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010300 break;
10301
10302 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010303 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010304 {
10305 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10306 "%s: setting interface Type to %s", __func__,
10307 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
10308
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010309 //Cancel any remain on channel for GO mode
10310 if (NL80211_IFTYPE_P2P_GO == type)
10311 {
10312 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
10313 }
Mohit Khanna0f232092012-09-11 14:46:08 -070010314 if (NL80211_IFTYPE_AP == type)
10315 {
10316 /* As Loading WLAN Driver one interface being created for p2p device
10317 * address. This will take one HW STA and the max number of clients
10318 * that can connect to softAP will be reduced by one. so while changing
10319 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
10320 * interface as it is not required in SoftAP mode.
10321 */
10322
10323 // Get P2P Adapter
10324 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
10325
10326 if (pP2pAdapter)
10327 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010328 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053010329 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070010330 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
10331 }
10332 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053010333 //Disable IMPS & BMPS for SAP/GO
10334 if(VOS_STATUS_E_FAILURE ==
10335 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
10336 {
10337 //Fail to Exit BMPS
10338 VOS_ASSERT(0);
10339 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053010340
10341 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
10342
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010343#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070010344
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010345 /* A Mutex Lock is introduced while changing the mode to
10346 * protect the concurrent access for the Adapters by TDLS
10347 * module.
10348 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010349 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010350#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010351 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053010352 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010353 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070010354 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10355 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010356#ifdef FEATURE_WLAN_TDLS
10357 mutex_unlock(&pHddCtx->tdls_lock);
10358#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010359 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
10360 (pConfig->apRandomBssidEnabled))
10361 {
10362 /* To meet Android requirements create a randomized
10363 MAC address of the form 02:1A:11:Fx:xx:xx */
10364 get_random_bytes(&ndev->dev_addr[3], 3);
10365 ndev->dev_addr[0] = 0x02;
10366 ndev->dev_addr[1] = 0x1A;
10367 ndev->dev_addr[2] = 0x11;
10368 ndev->dev_addr[3] |= 0xF0;
10369 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
10370 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080010371 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
10372 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010373 }
10374
Jeff Johnson295189b2012-06-20 16:38:30 -070010375 hdd_set_ap_ops( pAdapter->dev );
10376
Kiet Lam10841362013-11-01 11:36:50 +053010377 /* This is for only SAP mode where users can
10378 * control country through ini.
10379 * P2P GO follows station country code
10380 * acquired during the STA scanning. */
10381 if((NL80211_IFTYPE_AP == type) &&
10382 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
10383 {
10384 int status = 0;
10385 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
10386 "%s: setting country code from INI ", __func__);
10387 init_completion(&pAdapter->change_country_code);
10388 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
10389 (void *)(tSmeChangeCountryCallback)
10390 wlan_hdd_change_country_code_cb,
10391 pConfig->apCntryCode, pAdapter,
10392 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010393 eSIR_FALSE,
10394 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053010395 if (eHAL_STATUS_SUCCESS == status)
10396 {
10397 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010398 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053010399 &pAdapter->change_country_code,
10400 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010401 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053010402 {
10403 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010404 FL("SME Timed out while setting country code %ld"),
10405 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080010406
10407 if (pHddCtx->isLogpInProgress)
10408 {
10409 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10410 "%s: LOGP in Progress. Ignore!!!", __func__);
10411 return -EAGAIN;
10412 }
Kiet Lam10841362013-11-01 11:36:50 +053010413 }
10414 }
10415 else
10416 {
10417 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010418 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053010419 return -EINVAL;
10420 }
10421 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010422 status = hdd_init_ap_mode(pAdapter);
10423 if(status != VOS_STATUS_SUCCESS)
10424 {
10425 hddLog(VOS_TRACE_LEVEL_FATAL,
10426 "%s: Error initializing the ap mode", __func__);
10427 return -EINVAL;
10428 }
10429 hdd_set_conparam(1);
10430
Nirav Shah7e3c8132015-06-22 23:51:42 +053010431 status = hdd_sta_id_hash_attach(pAdapter);
10432 if (VOS_STATUS_SUCCESS != status)
10433 {
10434 hddLog(VOS_TRACE_LEVEL_ERROR,
10435 FL("Failed to initialize hash for AP"));
10436 return -EINVAL;
10437 }
10438
Jeff Johnson295189b2012-06-20 16:38:30 -070010439 /*interface type changed update in wiphy structure*/
10440 if(wdev)
10441 {
10442 wdev->iftype = type;
10443 pHddCtx->change_iface = type;
10444 }
10445 else
10446 {
10447 hddLog(VOS_TRACE_LEVEL_ERROR,
10448 "%s: ERROR !!!! Wireless dev is NULL", __func__);
10449 return -EINVAL;
10450 }
10451 goto done;
10452 }
10453
10454 default:
10455 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10456 __func__);
10457 return -EOPNOTSUPP;
10458 }
10459 }
10460 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010461 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010462 )
10463 {
10464 switch(type)
10465 {
10466 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010467 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010468 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053010469
10470 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010471#ifdef FEATURE_WLAN_TDLS
10472
10473 /* A Mutex Lock is introduced while changing the mode to
10474 * protect the concurrent access for the Adapters by TDLS
10475 * module.
10476 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010477 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010478#endif
c_hpothu002231a2015-02-05 14:58:51 +053010479 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010480 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010481 //Check for sub-string p2p to confirm its a p2p interface
10482 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010483 {
10484 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10485 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10486 }
10487 else
10488 {
10489 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010490 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010491 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010492 hdd_set_conparam(0);
10493 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010494 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
10495 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010496#ifdef FEATURE_WLAN_TDLS
10497 mutex_unlock(&pHddCtx->tdls_lock);
10498#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053010499 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070010500 if( VOS_STATUS_SUCCESS != status )
10501 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070010502 /* In case of JB, for P2P-GO, only change interface will be called,
10503 * This is the right place to enable back bmps_imps()
10504 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010505 if (pHddCtx->hdd_wlan_suspended)
10506 {
10507 hdd_set_pwrparams(pHddCtx);
10508 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010509 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010510 goto done;
10511 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010512 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010513 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010514 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10515 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010516 goto done;
10517 default:
10518 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10519 __func__);
10520 return -EOPNOTSUPP;
10521
10522 }
10523
10524 }
10525 else
10526 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010527 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
10528 __func__, hdd_device_modetoString(pAdapter->device_mode),
10529 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010530 return -EOPNOTSUPP;
10531 }
10532
10533
10534 if(pRoamProfile)
10535 {
10536 if ( LastBSSType != pRoamProfile->BSSType )
10537 {
10538 /*interface type changed update in wiphy structure*/
10539 wdev->iftype = type;
10540
10541 /*the BSS mode changed, We need to issue disconnect
10542 if connected or in IBSS disconnect state*/
10543 if ( hdd_connGetConnectedBssType(
10544 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
10545 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
10546 {
10547 /*need to issue a disconnect to CSR.*/
10548 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10549 if( eHAL_STATUS_SUCCESS ==
10550 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10551 pAdapter->sessionId,
10552 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10553 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010554 ret = wait_for_completion_interruptible_timeout(
10555 &pAdapter->disconnect_comp_var,
10556 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10557 if (ret <= 0)
10558 {
10559 hddLog(VOS_TRACE_LEVEL_ERROR,
10560 FL("wait on disconnect_comp_var failed %ld"), ret);
10561 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010562 }
10563 }
10564 }
10565 }
10566
10567done:
10568 /*set bitmask based on updated value*/
10569 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070010570
10571 /* Only STA mode support TM now
10572 * all other mode, TM feature should be disabled */
10573 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
10574 (~VOS_STA & pHddCtx->concurrency_mode) )
10575 {
10576 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
10577 }
10578
Jeff Johnson295189b2012-06-20 16:38:30 -070010579#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010580 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010581 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070010582 {
10583 //we are ok to do AMP
10584 pHddCtx->isAmpAllowed = VOS_TRUE;
10585 }
10586#endif //WLAN_BTAMP_FEATURE
10587 EXIT();
10588 return 0;
10589}
10590
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010591/*
10592 * FUNCTION: wlan_hdd_cfg80211_change_iface
10593 * wrapper function to protect the actual implementation from SSR.
10594 */
10595int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
10596 struct net_device *ndev,
10597 enum nl80211_iftype type,
10598 u32 *flags,
10599 struct vif_params *params
10600 )
10601{
10602 int ret;
10603
10604 vos_ssr_protect(__func__);
10605 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
10606 vos_ssr_unprotect(__func__);
10607
10608 return ret;
10609}
10610
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010611#ifdef FEATURE_WLAN_TDLS
10612static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010613 struct net_device *dev,
10614#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10615 const u8 *mac,
10616#else
10617 u8 *mac,
10618#endif
10619 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010620{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010621 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010622 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010623 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010624 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010625 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010626 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010627
10628 ENTER();
10629
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010630 if (!dev) {
10631 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
10632 return -EINVAL;
10633 }
10634
10635 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10636 if (!pAdapter) {
10637 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
10638 return -EINVAL;
10639 }
10640
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010641 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010642 {
10643 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10644 "Invalid arguments");
10645 return -EINVAL;
10646 }
Hoonki Lee27511902013-03-14 18:19:06 -070010647
10648 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
10649 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
10650 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010651 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070010652 "%s: TDLS mode is disabled OR not enabled in FW."
10653 MAC_ADDRESS_STR " Request declined.",
10654 __func__, MAC_ADDR_ARRAY(mac));
10655 return -ENOTSUPP;
10656 }
10657
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010658 if (pHddCtx->isLogpInProgress)
10659 {
10660 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10661 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053010662 wlan_hdd_tdls_set_link_status(pAdapter,
10663 mac,
10664 eTDLS_LINK_IDLE,
10665 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010666 return -EBUSY;
10667 }
10668
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010669 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053010670 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010671
10672 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010673 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010674 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
10675 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010676 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010677 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010678 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010679
10680 /* in add station, we accept existing valid staId if there is */
10681 if ((0 == update) &&
10682 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
10683 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010684 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010685 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010686 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010687 " link_status %d. staId %d. add station ignored.",
10688 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010689 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010690 return 0;
10691 }
10692 /* in change station, we accept only when staId is valid */
10693 if ((1 == update) &&
10694 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
10695 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
10696 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010697 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010698 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010699 "%s: " MAC_ADDRESS_STR
10700 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010701 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
10702 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
10703 mutex_unlock(&pHddCtx->tdls_lock);
10704 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010705 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010706 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010707
10708 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053010709 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010710 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010711 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10712 "%s: " MAC_ADDRESS_STR
10713 " TDLS setup is ongoing. Request declined.",
10714 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070010715 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010716 }
10717
10718 /* first to check if we reached to maximum supported TDLS peer.
10719 TODO: for now, return -EPERM looks working fine,
10720 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010721 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
10722 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010723 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010724 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10725 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010726 " TDLS Max peer already connected. Request declined."
10727 " Num of peers (%d), Max allowed (%d).",
10728 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
10729 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010730 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010731 }
10732 else
10733 {
10734 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010735 mutex_lock(&pHddCtx->tdls_lock);
10736 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010737 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010738 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010739 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10741 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
10742 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010743 return -EPERM;
10744 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010745 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010746 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010747 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053010748 wlan_hdd_tdls_set_link_status(pAdapter,
10749 mac,
10750 eTDLS_LINK_CONNECTING,
10751 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010752
Jeff Johnsond75fe012013-04-06 10:53:06 -070010753 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010754 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010755 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010756 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010757 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010758 if(StaParams->htcap_present)
10759 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010760 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010761 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010762 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010763 "ht_capa->extended_capabilities: %0x",
10764 StaParams->HTCap.extendedHtCapInfo);
10765 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010766 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010767 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010768 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010769 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010770 if(StaParams->vhtcap_present)
10771 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010773 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
10774 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
10775 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
10776 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010777 {
10778 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010779 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010780 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010781 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010782 "[%d]: %x ", i, StaParams->supported_rates[i]);
10783 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070010784 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010785 else if ((1 == update) && (NULL == StaParams))
10786 {
10787 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10788 "%s : update is true, but staParams is NULL. Error!", __func__);
10789 return -EPERM;
10790 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010791
10792 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
10793
10794 if (!update)
10795 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010796 /*Before adding sta make sure that device exited from BMPS*/
10797 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
10798 {
10799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10800 "%s: Adding tdls peer sta. Disable BMPS", __func__);
10801 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
10802 if (status != VOS_STATUS_SUCCESS) {
10803 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
10804 }
10805 }
10806
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010807 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010808 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010809 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010810 hddLog(VOS_TRACE_LEVEL_ERROR,
10811 FL("Failed to add TDLS peer STA. Enable Bmps"));
10812 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010813 return -EPERM;
10814 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010815 }
10816 else
10817 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010818 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010819 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010820 if (ret != eHAL_STATUS_SUCCESS) {
10821 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
10822 return -EPERM;
10823 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010824 }
10825
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010826 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010827 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
10828
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010829 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010830 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010831 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010832 "%s: timeout waiting for tdls add station indication %ld",
10833 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010834 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010835 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010836
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010837 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
10838 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010839 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010840 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010841 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010842 }
10843
10844 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070010845
10846error:
Atul Mittal115287b2014-07-08 13:26:33 +053010847 wlan_hdd_tdls_set_link_status(pAdapter,
10848 mac,
10849 eTDLS_LINK_IDLE,
10850 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010851 return -EPERM;
10852
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010853}
10854#endif
10855
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010856static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010857 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010858#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10859 const u8 *mac,
10860#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010861 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010862#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010863 struct station_parameters *params)
10864{
10865 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010866 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010867 hdd_context_t *pHddCtx;
10868 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010869 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010870 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010871#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010872 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010873 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010874 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010875#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010876
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010877 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010878
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010879 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010880 if ((NULL == pAdapter))
10881 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010882 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010883 "invalid adapter ");
10884 return -EINVAL;
10885 }
10886
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010887 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10888 TRACE_CODE_HDD_CHANGE_STATION,
10889 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053010890 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010891
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010892 ret = wlan_hdd_validate_context(pHddCtx);
10893 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053010894 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010895 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010896 }
10897
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010898 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10899
10900 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010901 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010902 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10903 "invalid HDD station context");
10904 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010905 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010906 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
10907
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010908 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10909 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070010910 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010911 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070010912 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010913 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070010914 WLANTL_STA_AUTHENTICATED);
10915
Gopichand Nakkala29149562013-05-10 21:43:41 +053010916 if (status != VOS_STATUS_SUCCESS)
10917 {
10918 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10919 "%s: Not able to change TL state to AUTHENTICATED", __func__);
10920 return -EINVAL;
10921 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010922 }
10923 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070010924 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
10925 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053010926#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010927 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
10928 StaParams.capability = params->capability;
10929 StaParams.uapsd_queues = params->uapsd_queues;
10930 StaParams.max_sp = params->max_sp;
10931
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010932 /* Convert (first channel , number of channels) tuple to
10933 * the total list of channels. This goes with the assumption
10934 * that if the first channel is < 14, then the next channels
10935 * are an incremental of 1 else an incremental of 4 till the number
10936 * of channels.
10937 */
10938 if (0 != params->supported_channels_len) {
10939 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
10940 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
10941 {
10942 int wifi_chan_index;
10943 StaParams.supported_channels[j] = params->supported_channels[i];
10944 wifi_chan_index =
10945 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
10946 no_of_channels = params->supported_channels[i+1];
10947 for(k=1; k <= no_of_channels; k++)
10948 {
10949 StaParams.supported_channels[j+1] =
10950 StaParams.supported_channels[j] + wifi_chan_index;
10951 j+=1;
10952 }
10953 }
10954 StaParams.supported_channels_len = j;
10955 }
10956 vos_mem_copy(StaParams.supported_oper_classes,
10957 params->supported_oper_classes,
10958 params->supported_oper_classes_len);
10959 StaParams.supported_oper_classes_len =
10960 params->supported_oper_classes_len;
10961
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010962 if (0 != params->ext_capab_len)
10963 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
10964 sizeof(StaParams.extn_capability));
10965
10966 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070010967 {
10968 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010969 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070010970 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010971
10972 StaParams.supported_rates_len = params->supported_rates_len;
10973
10974 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
10975 * The supported_rates array , for all the structures propogating till Add Sta
10976 * to the firmware has to be modified , if the supplicant (ieee80211) is
10977 * modified to send more rates.
10978 */
10979
10980 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
10981 */
10982 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
10983 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
10984
10985 if (0 != StaParams.supported_rates_len) {
10986 int i = 0;
10987 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
10988 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010989 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010990 "Supported Rates with Length %d", StaParams.supported_rates_len);
10991 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010992 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010993 "[%d]: %0x", i, StaParams.supported_rates[i]);
10994 }
10995
10996 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070010997 {
10998 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010999 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070011000 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070011001
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011002 if (0 != params->ext_capab_len ) {
11003 /*Define A Macro : TODO Sunil*/
11004 if ((1<<4) & StaParams.extn_capability[3]) {
11005 isBufSta = 1;
11006 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011007 /* TDLS Channel Switching Support */
11008 if ((1<<6) & StaParams.extn_capability[3]) {
11009 isOffChannelSupported = 1;
11010 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011011 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053011012 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
11013 &StaParams, isBufSta,
11014 isOffChannelSupported);
11015
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053011016 if (VOS_STATUS_SUCCESS != status) {
11017 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11018 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
11019 return -EINVAL;
11020 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011021 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
11022
11023 if (VOS_STATUS_SUCCESS != status) {
11024 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11025 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
11026 return -EINVAL;
11027 }
11028 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070011029#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053011030 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011031 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011032 return status;
11033}
11034
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011035#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
11036static int wlan_hdd_change_station(struct wiphy *wiphy,
11037 struct net_device *dev,
11038 const u8 *mac,
11039 struct station_parameters *params)
11040#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011041static int wlan_hdd_change_station(struct wiphy *wiphy,
11042 struct net_device *dev,
11043 u8 *mac,
11044 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011045#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011046{
11047 int ret;
11048
11049 vos_ssr_protect(__func__);
11050 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
11051 vos_ssr_unprotect(__func__);
11052
11053 return ret;
11054}
11055
Jeff Johnson295189b2012-06-20 16:38:30 -070011056/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011057 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011058 * This function is used to initialize the key information
11059 */
11060#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011061static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011062 struct net_device *ndev,
11063 u8 key_index, bool pairwise,
11064 const u8 *mac_addr,
11065 struct key_params *params
11066 )
11067#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011068static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011069 struct net_device *ndev,
11070 u8 key_index, const u8 *mac_addr,
11071 struct key_params *params
11072 )
11073#endif
11074{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011075 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011076 tCsrRoamSetKey setKey;
11077 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011078 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011079 v_U32_t roamId= 0xFF;
11080 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011081 hdd_hostapd_state_t *pHostapdState;
11082 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011083 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011084 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011085
11086 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011087
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011088 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11089 TRACE_CODE_HDD_CFG80211_ADD_KEY,
11090 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011091 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11092 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011093 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011094 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011095 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011096 }
11097
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011098 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11099 __func__, hdd_device_modetoString(pAdapter->device_mode),
11100 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011101
11102 if (CSR_MAX_NUM_KEY <= key_index)
11103 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011104 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011105 key_index);
11106
11107 return -EINVAL;
11108 }
11109
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011110 if (CSR_MAX_KEY_LEN < params->key_len)
11111 {
11112 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
11113 params->key_len);
11114
11115 return -EINVAL;
11116 }
11117
11118 hddLog(VOS_TRACE_LEVEL_INFO,
11119 "%s: called with key index = %d & key length %d",
11120 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011121
11122 /*extract key idx, key len and key*/
11123 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11124 setKey.keyId = key_index;
11125 setKey.keyLength = params->key_len;
11126 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
11127
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011128 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011129 {
11130 case WLAN_CIPHER_SUITE_WEP40:
11131 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11132 break;
11133
11134 case WLAN_CIPHER_SUITE_WEP104:
11135 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
11136 break;
11137
11138 case WLAN_CIPHER_SUITE_TKIP:
11139 {
11140 u8 *pKey = &setKey.Key[0];
11141 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
11142
11143 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
11144
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011145 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070011146
11147 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011148 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011149 |--------------|----------|----------|
11150 <---16bytes---><--8bytes--><--8bytes-->
11151
11152 */
11153 /*Sme expects the 32 bytes key to be in the below order
11154
11155 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011156 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011157 |--------------|----------|----------|
11158 <---16bytes---><--8bytes--><--8bytes-->
11159 */
11160 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011161 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070011162
11163 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011164 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011165
11166 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011167 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011168
11169
11170 break;
11171 }
11172
11173 case WLAN_CIPHER_SUITE_CCMP:
11174 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
11175 break;
11176
11177#ifdef FEATURE_WLAN_WAPI
11178 case WLAN_CIPHER_SUITE_SMS4:
11179 {
11180 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11181 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
11182 params->key, params->key_len);
11183 return 0;
11184 }
11185#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011186
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011187#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011188 case WLAN_CIPHER_SUITE_KRK:
11189 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
11190 break;
11191#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011192
11193#ifdef WLAN_FEATURE_11W
11194 case WLAN_CIPHER_SUITE_AES_CMAC:
11195 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070011196 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070011197#endif
11198
Jeff Johnson295189b2012-06-20 16:38:30 -070011199 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011200 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011201 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011202 status = -EOPNOTSUPP;
11203 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011204 }
11205
11206 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
11207 __func__, setKey.encType);
11208
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011209 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070011210#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11211 (!pairwise)
11212#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011213 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070011214#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011215 )
11216 {
11217 /* set group key*/
11218 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11219 "%s- %d: setting Broadcast key",
11220 __func__, __LINE__);
11221 setKey.keyDirection = eSIR_RX_ONLY;
11222 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11223 }
11224 else
11225 {
11226 /* set pairwise key*/
11227 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11228 "%s- %d: setting pairwise key",
11229 __func__, __LINE__);
11230 setKey.keyDirection = eSIR_TX_RX;
11231 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11232 }
11233 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
11234 {
11235 setKey.keyDirection = eSIR_TX_RX;
11236 /*Set the group key*/
11237 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11238 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070011239
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011240 if ( 0 != status )
11241 {
11242 hddLog(VOS_TRACE_LEVEL_ERROR,
11243 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011244 status = -EINVAL;
11245 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011246 }
11247 /*Save the keys here and call sme_RoamSetKey for setting
11248 the PTK after peer joins the IBSS network*/
11249 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
11250 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011251 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011252 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053011253 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
11254 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
11255 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011256 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011257 if( pHostapdState->bssState == BSS_START )
11258 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011259 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11260 vos_status = wlan_hdd_check_ula_done(pAdapter);
11261
11262 if ( vos_status != VOS_STATUS_SUCCESS )
11263 {
11264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11265 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11266 __LINE__, vos_status );
11267
11268 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11269
11270 status = -EINVAL;
11271 goto end;
11272 }
11273
Jeff Johnson295189b2012-06-20 16:38:30 -070011274 status = WLANSAP_SetKeySta( pVosContext, &setKey);
11275
11276 if ( status != eHAL_STATUS_SUCCESS )
11277 {
11278 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11279 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11280 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011281 status = -EINVAL;
11282 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011283 }
11284 }
11285
11286 /* Saving WEP keys */
11287 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
11288 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
11289 {
11290 //Save the wep key in ap context. Issue setkey after the BSS is started.
11291 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11292 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
11293 }
11294 else
11295 {
11296 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011297 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011298 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
11299 }
11300 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011301 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
11302 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011303 {
11304 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11305 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11306
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011307#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11308 if (!pairwise)
11309#else
11310 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
11311#endif
11312 {
11313 /* set group key*/
11314 if (pHddStaCtx->roam_info.deferKeyComplete)
11315 {
11316 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11317 "%s- %d: Perform Set key Complete",
11318 __func__, __LINE__);
11319 hdd_PerformRoamSetKeyComplete(pAdapter);
11320 }
11321 }
11322
Jeff Johnson295189b2012-06-20 16:38:30 -070011323 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
11324
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080011325 pWextState->roamProfile.Keys.defaultIndex = key_index;
11326
11327
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011328 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011329 params->key, params->key_len);
11330
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011331
Jeff Johnson295189b2012-06-20 16:38:30 -070011332 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11333
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011334 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011335 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011336 __func__, setKey.peerMac[0], setKey.peerMac[1],
11337 setKey.peerMac[2], setKey.peerMac[3],
11338 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011339 setKey.keyDirection);
11340
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011341 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053011342
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011343 if ( vos_status != VOS_STATUS_SUCCESS )
11344 {
11345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011346 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11347 __LINE__, vos_status );
11348
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011349 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011350
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011351 status = -EINVAL;
11352 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011353
11354 }
11355
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011356#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011357 /* The supplicant may attempt to set the PTK once pre-authentication
11358 is done. Save the key in the UMAC and include it in the ADD BSS
11359 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011360 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011361 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011362 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011363 hddLog(VOS_TRACE_LEVEL_INFO_MED,
11364 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011365 status = 0;
11366 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011367 }
11368 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
11369 {
11370 hddLog(VOS_TRACE_LEVEL_ERROR,
11371 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011372 status = -EINVAL;
11373 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011374 }
11375#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070011376
11377 /* issue set key request to SME*/
11378 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11379 pAdapter->sessionId, &setKey, &roamId );
11380
11381 if ( 0 != status )
11382 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011383 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011384 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
11385 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011386 status = -EINVAL;
11387 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011388 }
11389
11390
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011391 /* in case of IBSS as there was no information available about WEP keys during
11392 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070011393 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011394 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
11395 !( ( IW_AUTH_KEY_MGMT_802_1X
11396 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070011397 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
11398 )
11399 &&
11400 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
11401 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
11402 )
11403 )
11404 {
11405 setKey.keyDirection = eSIR_RX_ONLY;
11406 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11407
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011408 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011409 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011410 __func__, setKey.peerMac[0], setKey.peerMac[1],
11411 setKey.peerMac[2], setKey.peerMac[3],
11412 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011413 setKey.keyDirection);
11414
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011415 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011416 pAdapter->sessionId, &setKey, &roamId );
11417
11418 if ( 0 != status )
11419 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011420 hddLog(VOS_TRACE_LEVEL_ERROR,
11421 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011422 __func__, status);
11423 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011424 status = -EINVAL;
11425 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011426 }
11427 }
11428 }
11429
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011430end:
11431 /* Need to clear any trace of key value in the memory.
11432 * Thus zero out the memory even though it is local
11433 * variable.
11434 */
11435 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011436 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011437 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011438}
11439
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011440#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11441static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11442 struct net_device *ndev,
11443 u8 key_index, bool pairwise,
11444 const u8 *mac_addr,
11445 struct key_params *params
11446 )
11447#else
11448static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11449 struct net_device *ndev,
11450 u8 key_index, const u8 *mac_addr,
11451 struct key_params *params
11452 )
11453#endif
11454{
11455 int ret;
11456 vos_ssr_protect(__func__);
11457#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11458 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
11459 mac_addr, params);
11460#else
11461 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
11462 params);
11463#endif
11464 vos_ssr_unprotect(__func__);
11465
11466 return ret;
11467}
11468
Jeff Johnson295189b2012-06-20 16:38:30 -070011469/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011470 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011471 * This function is used to get the key information
11472 */
11473#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011474static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011475 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011476 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011477 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011478 const u8 *mac_addr, void *cookie,
11479 void (*callback)(void *cookie, struct key_params*)
11480 )
11481#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011482static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011483 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011484 struct net_device *ndev,
11485 u8 key_index, const u8 *mac_addr, void *cookie,
11486 void (*callback)(void *cookie, struct key_params*)
11487 )
11488#endif
11489{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011490 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011491 hdd_wext_state_t *pWextState = NULL;
11492 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011493 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011494 hdd_context_t *pHddCtx;
11495 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011496
11497 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011498
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011499 if (NULL == pAdapter)
11500 {
11501 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11502 "%s: HDD adapter is Null", __func__);
11503 return -ENODEV;
11504 }
11505
11506 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11507 ret = wlan_hdd_validate_context(pHddCtx);
11508 if (0 != ret)
11509 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011510 return ret;
11511 }
11512
11513 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11514 pRoamProfile = &(pWextState->roamProfile);
11515
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011516 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11517 __func__, hdd_device_modetoString(pAdapter->device_mode),
11518 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011519
Jeff Johnson295189b2012-06-20 16:38:30 -070011520 memset(&params, 0, sizeof(params));
11521
11522 if (CSR_MAX_NUM_KEY <= key_index)
11523 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011524 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011525 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011526 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011527
11528 switch(pRoamProfile->EncryptionType.encryptionType[0])
11529 {
11530 case eCSR_ENCRYPT_TYPE_NONE:
11531 params.cipher = IW_AUTH_CIPHER_NONE;
11532 break;
11533
11534 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
11535 case eCSR_ENCRYPT_TYPE_WEP40:
11536 params.cipher = WLAN_CIPHER_SUITE_WEP40;
11537 break;
11538
11539 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
11540 case eCSR_ENCRYPT_TYPE_WEP104:
11541 params.cipher = WLAN_CIPHER_SUITE_WEP104;
11542 break;
11543
11544 case eCSR_ENCRYPT_TYPE_TKIP:
11545 params.cipher = WLAN_CIPHER_SUITE_TKIP;
11546 break;
11547
11548 case eCSR_ENCRYPT_TYPE_AES:
11549 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
11550 break;
11551
11552 default:
11553 params.cipher = IW_AUTH_CIPHER_NONE;
11554 break;
11555 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011556
c_hpothuaaf19692014-05-17 17:01:48 +053011557 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11558 TRACE_CODE_HDD_CFG80211_GET_KEY,
11559 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011560
Jeff Johnson295189b2012-06-20 16:38:30 -070011561 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
11562 params.seq_len = 0;
11563 params.seq = NULL;
11564 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
11565 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011566 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011567 return 0;
11568}
11569
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011570#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11571static int wlan_hdd_cfg80211_get_key(
11572 struct wiphy *wiphy,
11573 struct net_device *ndev,
11574 u8 key_index, bool pairwise,
11575 const u8 *mac_addr, void *cookie,
11576 void (*callback)(void *cookie, struct key_params*)
11577 )
11578#else
11579static int wlan_hdd_cfg80211_get_key(
11580 struct wiphy *wiphy,
11581 struct net_device *ndev,
11582 u8 key_index, const u8 *mac_addr, void *cookie,
11583 void (*callback)(void *cookie, struct key_params*)
11584 )
11585#endif
11586{
11587 int ret;
11588
11589 vos_ssr_protect(__func__);
11590#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11591 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
11592 mac_addr, cookie, callback);
11593#else
11594 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
11595 callback);
11596#endif
11597 vos_ssr_unprotect(__func__);
11598
11599 return ret;
11600}
11601
Jeff Johnson295189b2012-06-20 16:38:30 -070011602/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011603 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011604 * This function is used to delete the key information
11605 */
11606#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011607static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011608 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011609 u8 key_index,
11610 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011611 const u8 *mac_addr
11612 )
11613#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011614static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011615 struct net_device *ndev,
11616 u8 key_index,
11617 const u8 *mac_addr
11618 )
11619#endif
11620{
11621 int status = 0;
11622
11623 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011624 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070011625 //it is observed that this is invalidating peer
11626 //key index whenever re-key is done. This is affecting data link.
11627 //It should be ok to ignore del_key.
11628#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011629 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
11630 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011631 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11632 tCsrRoamSetKey setKey;
11633 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011634
Jeff Johnson295189b2012-06-20 16:38:30 -070011635 ENTER();
11636
11637 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
11638 __func__,pAdapter->device_mode);
11639
11640 if (CSR_MAX_NUM_KEY <= key_index)
11641 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011642 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011643 key_index);
11644
11645 return -EINVAL;
11646 }
11647
11648 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11649 setKey.keyId = key_index;
11650
11651 if (mac_addr)
11652 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11653 else
11654 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
11655
11656 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
11657
11658 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011659 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011660 )
11661 {
11662
11663 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070011664 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11665 if( pHostapdState->bssState == BSS_START)
11666 {
11667 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011668
Jeff Johnson295189b2012-06-20 16:38:30 -070011669 if ( status != eHAL_STATUS_SUCCESS )
11670 {
11671 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11672 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11673 __LINE__, status );
11674 }
11675 }
11676 }
11677 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011678 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070011679 )
11680 {
11681 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11682
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011683 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11684
11685 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011686 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011687 __func__, setKey.peerMac[0], setKey.peerMac[1],
11688 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070011689 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011690 if(pAdapter->sessionCtx.station.conn_info.connState ==
11691 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070011692 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011693 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011694 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011695
Jeff Johnson295189b2012-06-20 16:38:30 -070011696 if ( 0 != status )
11697 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011698 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011699 "%s: sme_RoamSetKey failure, returned %d",
11700 __func__, status);
11701 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11702 return -EINVAL;
11703 }
11704 }
11705 }
11706#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011707 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011708 return status;
11709}
11710
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011711#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11712static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11713 struct net_device *ndev,
11714 u8 key_index,
11715 bool pairwise,
11716 const u8 *mac_addr
11717 )
11718#else
11719static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11720 struct net_device *ndev,
11721 u8 key_index,
11722 const u8 *mac_addr
11723 )
11724#endif
11725{
11726 int ret;
11727
11728 vos_ssr_protect(__func__);
11729#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11730 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
11731 mac_addr);
11732#else
11733 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
11734#endif
11735 vos_ssr_unprotect(__func__);
11736
11737 return ret;
11738}
11739
Jeff Johnson295189b2012-06-20 16:38:30 -070011740/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011741 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011742 * This function is used to set the default tx key index
11743 */
11744#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011745static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011746 struct net_device *ndev,
11747 u8 key_index,
11748 bool unicast, bool multicast)
11749#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011750static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011751 struct net_device *ndev,
11752 u8 key_index)
11753#endif
11754{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011755 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011756 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011757 hdd_wext_state_t *pWextState;
11758 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011759 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011760
11761 ENTER();
11762
Gopichand Nakkala29149562013-05-10 21:43:41 +053011763 if ((NULL == pAdapter))
11764 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011765 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011766 "invalid adapter");
11767 return -EINVAL;
11768 }
11769
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011770 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11771 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
11772 pAdapter->sessionId, key_index));
11773
Gopichand Nakkala29149562013-05-10 21:43:41 +053011774 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11775 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11776
11777 if ((NULL == pWextState) || (NULL == pHddStaCtx))
11778 {
11779 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11780 "invalid Wext state or HDD context");
11781 return -EINVAL;
11782 }
11783
Arif Hussain6d2a3322013-11-17 19:50:10 -080011784 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011785 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011786
Jeff Johnson295189b2012-06-20 16:38:30 -070011787 if (CSR_MAX_NUM_KEY <= key_index)
11788 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011789 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011790 key_index);
11791
11792 return -EINVAL;
11793 }
11794
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011795 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11796 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011797 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011798 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011799 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011800 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011801
Jeff Johnson295189b2012-06-20 16:38:30 -070011802 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011803 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011804 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011805 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011806 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080011807 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011808 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080011809 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070011810 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011811 {
11812 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070011813 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011814
Jeff Johnson295189b2012-06-20 16:38:30 -070011815 tCsrRoamSetKey setKey;
11816 v_U32_t roamId= 0xFF;
11817 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011818
11819 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011820 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011821
Jeff Johnson295189b2012-06-20 16:38:30 -070011822 Keys->defaultIndex = (u8)key_index;
11823 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11824 setKey.keyId = key_index;
11825 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011826
11827 vos_mem_copy(&setKey.Key[0],
11828 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011829 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011830
Gopichand Nakkala29149562013-05-10 21:43:41 +053011831 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011832
11833 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070011834 &pHddStaCtx->conn_info.bssId[0],
11835 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011836
Gopichand Nakkala29149562013-05-10 21:43:41 +053011837 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
11838 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
11839 eCSR_ENCRYPT_TYPE_WEP104)
11840 {
11841 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
11842 even though ap is configured for WEP-40 encryption. In this canse the key length
11843 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
11844 type(104) and switching encryption type to 40*/
11845 pWextState->roamProfile.EncryptionType.encryptionType[0] =
11846 eCSR_ENCRYPT_TYPE_WEP40;
11847 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
11848 eCSR_ENCRYPT_TYPE_WEP40;
11849 }
11850
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011851 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011852 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011853
Jeff Johnson295189b2012-06-20 16:38:30 -070011854 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011855 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011856 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011857
Jeff Johnson295189b2012-06-20 16:38:30 -070011858 if ( 0 != status )
11859 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011860 hddLog(VOS_TRACE_LEVEL_ERROR,
11861 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011862 status);
11863 return -EINVAL;
11864 }
11865 }
11866 }
11867
11868 /* In SoftAp mode setting key direction for default mode */
11869 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
11870 {
11871 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
11872 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
11873 (eCSR_ENCRYPT_TYPE_AES !=
11874 pWextState->roamProfile.EncryptionType.encryptionType[0])
11875 )
11876 {
11877 /* Saving key direction for default key index to TX default */
11878 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11879 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
11880 }
11881 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011882 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011883 return status;
11884}
11885
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011886#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11887static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
11888 struct net_device *ndev,
11889 u8 key_index,
11890 bool unicast, bool multicast)
11891#else
11892static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
11893 struct net_device *ndev,
11894 u8 key_index)
11895#endif
11896{
11897 int ret;
11898 vos_ssr_protect(__func__);
11899#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11900 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
11901 multicast);
11902#else
11903 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
11904#endif
11905 vos_ssr_unprotect(__func__);
11906
11907 return ret;
11908}
11909
Jeff Johnson295189b2012-06-20 16:38:30 -070011910/*
11911 * FUNCTION: wlan_hdd_cfg80211_inform_bss
11912 * This function is used to inform the BSS details to nl80211 interface.
11913 */
11914static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
11915 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
11916{
11917 struct net_device *dev = pAdapter->dev;
11918 struct wireless_dev *wdev = dev->ieee80211_ptr;
11919 struct wiphy *wiphy = wdev->wiphy;
11920 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
11921 int chan_no;
11922 int ie_length;
11923 const char *ie;
11924 unsigned int freq;
11925 struct ieee80211_channel *chan;
11926 int rssi = 0;
11927 struct cfg80211_bss *bss = NULL;
11928
Jeff Johnson295189b2012-06-20 16:38:30 -070011929 if( NULL == pBssDesc )
11930 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011931 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011932 return bss;
11933 }
11934
11935 chan_no = pBssDesc->channelId;
11936 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
11937 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
11938
11939 if( NULL == ie )
11940 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011941 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011942 return bss;
11943 }
11944
11945#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
11946 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
11947 {
11948 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
11949 }
11950 else
11951 {
11952 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
11953 }
11954#else
11955 freq = ieee80211_channel_to_frequency(chan_no);
11956#endif
11957
11958 chan = __ieee80211_get_channel(wiphy, freq);
11959
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053011960 if (!chan) {
11961 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
11962 return NULL;
11963 }
11964
Abhishek Singhaee43942014-06-16 18:55:47 +053011965 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070011966
Anand N Sunkad9f80b742015-07-30 20:05:51 +053011967 return cfg80211_inform_bss(wiphy, chan,
11968#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11969 CFG80211_BSS_FTYPE_UNKNOWN,
11970#endif
11971 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011972 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070011973 pBssDesc->capabilityInfo,
11974 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053011975 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070011976}
11977
11978
11979
11980/*
11981 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
11982 * This function is used to inform the BSS details to nl80211 interface.
11983 */
11984struct cfg80211_bss*
11985wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
11986 tSirBssDescription *bss_desc
11987 )
11988{
11989 /*
11990 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
11991 already exists in bss data base of cfg80211 for that particular BSS ID.
11992 Using cfg80211_inform_bss_frame to update the bss entry instead of
11993 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
11994 now there is no possibility to get the mgmt(probe response) frame from PE,
11995 converting bss_desc to ieee80211_mgmt(probe response) and passing to
11996 cfg80211_inform_bss_frame.
11997 */
11998 struct net_device *dev = pAdapter->dev;
11999 struct wireless_dev *wdev = dev->ieee80211_ptr;
12000 struct wiphy *wiphy = wdev->wiphy;
12001 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012002#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12003 qcom_ie_age *qie_age = NULL;
12004 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
12005#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012006 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012007#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012008 const char *ie =
12009 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
12010 unsigned int freq;
12011 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012012 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012013 struct cfg80211_bss *bss_status = NULL;
12014 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
12015 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070012016 hdd_context_t *pHddCtx;
12017 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070012018#ifdef WLAN_OPEN_SOURCE
12019 struct timespec ts;
12020#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012021
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012022
Wilson Yangf80a0542013-10-07 13:02:37 -070012023 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12024 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070012025 if (0 != status)
12026 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012027 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012028 }
12029
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053012030 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070012031 if (!mgmt)
12032 {
12033 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12034 "%s: memory allocation failed ", __func__);
12035 return NULL;
12036 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012037
Jeff Johnson295189b2012-06-20 16:38:30 -070012038 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012039
12040#ifdef WLAN_OPEN_SOURCE
12041 /* Android does not want the timestamp from the frame.
12042 Instead it wants a monotonic increasing value */
12043 get_monotonic_boottime(&ts);
12044 mgmt->u.probe_resp.timestamp =
12045 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
12046#else
12047 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012048 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
12049 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070012050
12051#endif
12052
Jeff Johnson295189b2012-06-20 16:38:30 -070012053 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
12054 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012055
12056#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12057 /* GPS Requirement: need age ie per entry. Using vendor specific. */
12058 /* Assuming this is the last IE, copy at the end */
12059 ie_length -=sizeof(qcom_ie_age);
12060 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
12061 qie_age->element_id = QCOM_VENDOR_IE_ID;
12062 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
12063 qie_age->oui_1 = QCOM_OUI1;
12064 qie_age->oui_2 = QCOM_OUI2;
12065 qie_age->oui_3 = QCOM_OUI3;
12066 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
12067 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
12068#endif
12069
Jeff Johnson295189b2012-06-20 16:38:30 -070012070 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053012071 if (bss_desc->fProbeRsp)
12072 {
12073 mgmt->frame_control |=
12074 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
12075 }
12076 else
12077 {
12078 mgmt->frame_control |=
12079 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
12080 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012081
12082#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012083 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012084 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
12085 {
12086 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12087 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012088 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012089 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
12090
12091 {
12092 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12093 }
12094 else
12095 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012096 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
12097 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070012098 kfree(mgmt);
12099 return NULL;
12100 }
12101#else
12102 freq = ieee80211_channel_to_frequency(chan_no);
12103#endif
12104 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012105 /*when the band is changed on the fly using the GUI, three things are done
12106 * 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)
12107 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
12108 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
12109 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
12110 * and discards the channels correponding to previous band and calls back with zero bss results.
12111 * 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
12112 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
12113 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
12114 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
12115 * So drop the bss and continue to next bss.
12116 */
12117 if(chan == NULL)
12118 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012119 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070012120 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012121 return NULL;
12122 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053012123 /*To keep the rssi icon of the connected AP in the scan window
12124 *and the rssi icon of the wireless networks in sync
12125 * */
12126 if (( eConnectionState_Associated ==
12127 pAdapter->sessionCtx.station.conn_info.connState ) &&
12128 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
12129 pAdapter->sessionCtx.station.conn_info.bssId,
12130 WNI_CFG_BSSID_LEN)) &&
12131 (pHddCtx->hdd_wlan_suspended == FALSE))
12132 {
12133 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
12134 rssi = (pAdapter->rssi * 100);
12135 }
12136 else
12137 {
12138 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
12139 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012140
Nirav Shah20ac06f2013-12-12 18:14:06 +053012141 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053012142 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
12143 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053012144
Jeff Johnson295189b2012-06-20 16:38:30 -070012145 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
12146 frame_len, rssi, GFP_KERNEL);
12147 kfree(mgmt);
12148 return bss_status;
12149}
12150
12151/*
12152 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
12153 * This function is used to update the BSS data base of CFG8011
12154 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012155struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012156 tCsrRoamInfo *pRoamInfo
12157 )
12158{
12159 tCsrRoamConnectedProfile roamProfile;
12160 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12161 struct cfg80211_bss *bss = NULL;
12162
12163 ENTER();
12164
12165 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
12166 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
12167
12168 if (NULL != roamProfile.pBssDesc)
12169 {
Girish Gowlif4b68022014-08-28 23:18:57 +053012170 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12171 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070012172
12173 if (NULL == bss)
12174 {
12175 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
12176 __func__);
12177 }
12178
12179 sme_RoamFreeConnectProfile(hHal, &roamProfile);
12180 }
12181 else
12182 {
12183 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
12184 __func__);
12185 }
12186 return bss;
12187}
12188
12189/*
12190 * FUNCTION: wlan_hdd_cfg80211_update_bss
12191 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012192static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
12193 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070012194 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012195{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012196 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012197 tCsrScanResultInfo *pScanResult;
12198 eHalStatus status = 0;
12199 tScanResultHandle pResult;
12200 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012201 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012202 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012203 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012204
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012205 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12206 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
12207 NO_SESSION, pAdapter->sessionId));
12208
Wilson Yangf80a0542013-10-07 13:02:37 -070012209 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12210
12211 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070012212 {
Wilson Yangf80a0542013-10-07 13:02:37 -070012213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12214 "%s:LOGP in Progress. Ignore!!!",__func__);
12215 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070012216 }
12217
Wilson Yangf80a0542013-10-07 13:02:37 -070012218
12219 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053012220 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070012221 {
12222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12223 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
12224 return VOS_STATUS_E_PERM;
12225 }
12226
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012227 if (pAdapter->request != NULL)
12228 {
12229 if ((pAdapter->request->n_ssids == 1)
12230 && (pAdapter->request->ssids != NULL)
12231 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
12232 is_p2p_scan = true;
12233 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012234 /*
12235 * start getting scan results and populate cgf80211 BSS database
12236 */
12237 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
12238
12239 /* no scan results */
12240 if (NULL == pResult)
12241 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012242 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
12243 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053012244 wlan_hdd_get_frame_logs(pAdapter,
12245 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070012246 return status;
12247 }
12248
12249 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
12250
12251 while (pScanResult)
12252 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012253 /*
12254 * cfg80211_inform_bss() is not updating ie field of bss entry, if
12255 * entry already exists in bss data base of cfg80211 for that
12256 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
12257 * bss entry instead of cfg80211_inform_bss, But this call expects
12258 * mgmt packet as input. As of now there is no possibility to get
12259 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070012260 * ieee80211_mgmt(probe response) and passing to c
12261 * fg80211_inform_bss_frame.
12262 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012263 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
12264 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
12265 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012266 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12267 continue; //Skip the non p2p bss entries
12268 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012269 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12270 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012271
Jeff Johnson295189b2012-06-20 16:38:30 -070012272
12273 if (NULL == bss_status)
12274 {
12275 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012276 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012277 }
12278 else
12279 {
Yue Maf49ba872013-08-19 12:04:25 -070012280 cfg80211_put_bss(
12281#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
12282 wiphy,
12283#endif
12284 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070012285 }
12286
12287 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12288 }
12289
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012290 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012291 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012292 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012293}
12294
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012295void
12296hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
12297{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012298 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080012299 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012300} /****** end hddPrintMacAddr() ******/
12301
12302void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012303hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012304{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012305 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012306 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012307 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
12308 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
12309 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012310} /****** end hddPrintPmkId() ******/
12311
12312//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
12313//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
12314
12315//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
12316//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
12317
12318#define dump_bssid(bssid) \
12319 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012320 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
12321 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012322 }
12323
12324#define dump_pmkid(pMac, pmkid) \
12325 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012326 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
12327 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012328 }
12329
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070012330#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012331/*
12332 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
12333 * This function is used to notify the supplicant of a new PMKSA candidate.
12334 */
12335int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012336 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012337 int index, bool preauth )
12338{
Jeff Johnsone7245742012-09-05 17:12:55 -070012339#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012340 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012341 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012342
12343 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070012344 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012345
12346 if( NULL == pRoamInfo )
12347 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012348 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012349 return -EINVAL;
12350 }
12351
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012352 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
12353 {
12354 dump_bssid(pRoamInfo->bssid);
12355 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012356 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012357 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012358#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012359 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012360}
12361#endif //FEATURE_WLAN_LFR
12362
Yue Maef608272013-04-08 23:09:17 -070012363#ifdef FEATURE_WLAN_LFR_METRICS
12364/*
12365 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
12366 * 802.11r/LFR metrics reporting function to report preauth initiation
12367 *
12368 */
12369#define MAX_LFR_METRICS_EVENT_LENGTH 100
12370VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
12371 tCsrRoamInfo *pRoamInfo)
12372{
12373 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12374 union iwreq_data wrqu;
12375
12376 ENTER();
12377
12378 if (NULL == pAdapter)
12379 {
12380 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12381 return VOS_STATUS_E_FAILURE;
12382 }
12383
12384 /* create the event */
12385 memset(&wrqu, 0, sizeof(wrqu));
12386 memset(metrics_notification, 0, sizeof(metrics_notification));
12387
12388 wrqu.data.pointer = metrics_notification;
12389 wrqu.data.length = scnprintf(metrics_notification,
12390 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
12391 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12392
12393 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12394
12395 EXIT();
12396
12397 return VOS_STATUS_SUCCESS;
12398}
12399
12400/*
12401 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
12402 * 802.11r/LFR metrics reporting function to report preauth completion
12403 * or failure
12404 */
12405VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
12406 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
12407{
12408 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12409 union iwreq_data wrqu;
12410
12411 ENTER();
12412
12413 if (NULL == pAdapter)
12414 {
12415 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12416 return VOS_STATUS_E_FAILURE;
12417 }
12418
12419 /* create the event */
12420 memset(&wrqu, 0, sizeof(wrqu));
12421 memset(metrics_notification, 0, sizeof(metrics_notification));
12422
12423 scnprintf(metrics_notification, sizeof(metrics_notification),
12424 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
12425 MAC_ADDR_ARRAY(pRoamInfo->bssid));
12426
12427 if (1 == preauth_status)
12428 strncat(metrics_notification, " TRUE", 5);
12429 else
12430 strncat(metrics_notification, " FALSE", 6);
12431
12432 wrqu.data.pointer = metrics_notification;
12433 wrqu.data.length = strlen(metrics_notification);
12434
12435 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12436
12437 EXIT();
12438
12439 return VOS_STATUS_SUCCESS;
12440}
12441
12442/*
12443 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
12444 * 802.11r/LFR metrics reporting function to report handover initiation
12445 *
12446 */
12447VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
12448 tCsrRoamInfo *pRoamInfo)
12449{
12450 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12451 union iwreq_data wrqu;
12452
12453 ENTER();
12454
12455 if (NULL == pAdapter)
12456 {
12457 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12458 return VOS_STATUS_E_FAILURE;
12459 }
12460
12461 /* create the event */
12462 memset(&wrqu, 0, sizeof(wrqu));
12463 memset(metrics_notification, 0, sizeof(metrics_notification));
12464
12465 wrqu.data.pointer = metrics_notification;
12466 wrqu.data.length = scnprintf(metrics_notification,
12467 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
12468 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12469
12470 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12471
12472 EXIT();
12473
12474 return VOS_STATUS_SUCCESS;
12475}
12476#endif
12477
Jeff Johnson295189b2012-06-20 16:38:30 -070012478/*
12479 * FUNCTION: hdd_cfg80211_scan_done_callback
12480 * scanning callback function, called after finishing scan
12481 *
12482 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012483static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070012484 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
12485{
12486 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012487 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070012488 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012489 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012490 struct cfg80211_scan_request *req = NULL;
12491 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012492 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012493 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012494 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012495 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012496
12497 ENTER();
12498
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012499 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053012500 if (NULL == pHddCtx) {
12501 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012502 goto allow_suspend;
12503 }
12504
12505 pScanInfo = &pHddCtx->scan_info;
12506
Jeff Johnson295189b2012-06-20 16:38:30 -070012507 hddLog(VOS_TRACE_LEVEL_INFO,
12508 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080012509 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012510 __func__, halHandle, pContext, (int) scanId, (int) status);
12511
Kiet Lamac06e2c2013-10-23 16:25:07 +053012512 pScanInfo->mScanPendingCounter = 0;
12513
Jeff Johnson295189b2012-06-20 16:38:30 -070012514 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012515 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070012516 &pScanInfo->scan_req_completion_event,
12517 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012518 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070012519 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012520 hddLog(VOS_TRACE_LEVEL_ERROR,
12521 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070012522 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012523 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012524 }
12525
Yue Maef608272013-04-08 23:09:17 -070012526 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012527 {
12528 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012529 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012530 }
12531
12532 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012533 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070012534 {
12535 hddLog(VOS_TRACE_LEVEL_INFO,
12536 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080012537 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070012538 (int) scanId);
12539 }
12540
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012541 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012542 pAdapter);
12543
12544 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012545 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012546
12547
12548 /* If any client wait scan result through WEXT
12549 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012550 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070012551 {
12552 /* The other scan request waiting for current scan finish
12553 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012554 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012555 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012556 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070012557 }
12558 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012559 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012560 {
12561 struct net_device *dev = pAdapter->dev;
12562 union iwreq_data wrqu;
12563 int we_event;
12564 char *msg;
12565
12566 memset(&wrqu, '\0', sizeof(wrqu));
12567 we_event = SIOCGIWSCAN;
12568 msg = NULL;
12569 wireless_send_event(dev, we_event, &wrqu, msg);
12570 }
12571 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012572 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012573
12574 /* Get the Scan Req */
12575 req = pAdapter->request;
12576
12577 if (!req)
12578 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012579 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012580 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070012581 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012582 }
12583
Jeff Johnson295189b2012-06-20 16:38:30 -070012584 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070012585 /* Scan is no longer pending */
12586 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012587
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012588 /* last_scan_timestamp is used to decide if new scan
12589 * is needed or not on station interface. If last station
12590 * scan time and new station scan time is less then
12591 * last_scan_timestamp ; driver will return cached scan.
12592 */
12593 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
12594 {
12595 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
12596
12597 if ( req->n_channels )
12598 {
12599 for (i = 0; i < req->n_channels ; i++ )
12600 {
12601 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
12602 }
12603 /* store no of channel scanned */
12604 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
12605 }
12606
12607 }
12608
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070012609 /*
12610 * cfg80211_scan_done informing NL80211 about completion
12611 * of scanning
12612 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012613 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
12614 {
12615 aborted = true;
12616 }
12617 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080012618 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070012619
Siddharth Bhal76972212014-10-15 16:22:51 +053012620 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
12621 /* Generate new random mac addr for next scan */
12622 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
12623 hdd_processSpoofMacAddrRequest(pHddCtx);
12624 }
12625
Jeff Johnsone7245742012-09-05 17:12:55 -070012626allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012627 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012628 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012629
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012630 /* Acquire wakelock to handle the case where APP's tries to suspend
12631 * immediatly after the driver gets connect request(i.e after scan)
12632 * from supplicant, this result in app's is suspending and not able
12633 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012634 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012635
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012636#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053012637 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012638#endif
12639
Jeff Johnson295189b2012-06-20 16:38:30 -070012640 EXIT();
12641 return 0;
12642}
12643
12644/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053012645 * FUNCTION: hdd_isConnectionInProgress
12646 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012647 *
12648 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012649v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012650{
12651 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12652 hdd_station_ctx_t *pHddStaCtx = NULL;
12653 hdd_adapter_t *pAdapter = NULL;
12654 VOS_STATUS status = 0;
12655 v_U8_t staId = 0;
12656 v_U8_t *staMac = NULL;
12657
c_hpothu9b781ba2013-12-30 20:57:45 +053012658 if (TRUE == pHddCtx->btCoexModeSet)
12659 {
12660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053012661 FL("BTCoex Mode operation in progress"));
12662 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053012663 }
12664
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012665 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12666
12667 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
12668 {
12669 pAdapter = pAdapterNode->pAdapter;
12670
12671 if( pAdapter )
12672 {
12673 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012674 "%s: Adapter with device mode %s (%d) exists",
12675 __func__, hdd_device_modetoString(pAdapter->device_mode),
12676 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012677 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053012678 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12679 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
12680 (eConnectionState_Connecting ==
12681 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12682 {
12683 hddLog(VOS_TRACE_LEVEL_ERROR,
12684 "%s: %p(%d) Connection is in progress", __func__,
12685 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12686 return VOS_TRUE;
12687 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012688 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053012689 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012690 {
12691 hddLog(VOS_TRACE_LEVEL_ERROR,
12692 "%s: %p(%d) Reassociation is in progress", __func__,
12693 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12694 return VOS_TRUE;
12695 }
12696 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012697 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12698 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012699 {
12700 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12701 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012702 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012703 {
12704 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
12705 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012706 "%s: client " MAC_ADDRESS_STR
12707 " is in the middle of WPS/EAPOL exchange.", __func__,
12708 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012709 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012710 }
12711 }
12712 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
12713 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
12714 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012715 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12716 ptSapContext pSapCtx = NULL;
12717 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12718 if(pSapCtx == NULL){
12719 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12720 FL("psapCtx is NULL"));
12721 return VOS_FALSE;
12722 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012723 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
12724 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012725 if ((pSapCtx->aStaInfo[staId].isUsed) &&
12726 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012727 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012728 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012729
12730 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012731 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
12732 "middle of WPS/EAPOL exchange.", __func__,
12733 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012734 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012735 }
12736 }
12737 }
12738 }
12739 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12740 pAdapterNode = pNext;
12741 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053012742 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012743}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012744
12745/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012746 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070012747 * this scan respond to scan trigger and update cfg80211 scan database
12748 * later, scan dump command can be used to recieve scan results
12749 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012750int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080012751#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12752 struct net_device *dev,
12753#endif
12754 struct cfg80211_scan_request *request)
12755{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012756 hdd_adapter_t *pAdapter = NULL;
12757 hdd_context_t *pHddCtx = NULL;
12758 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012759 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012760 tCsrScanRequest scanRequest;
12761 tANI_U8 *channelList = NULL, i;
12762 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012763 int status;
12764 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012765 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012766 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053012767 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053012768 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053012769 v_S7_t rssi=0;
12770 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012771
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012772#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
12773 struct net_device *dev = NULL;
12774 if (NULL == request)
12775 {
12776 hddLog(VOS_TRACE_LEVEL_ERROR,
12777 "%s: scan req param null", __func__);
12778 return -EINVAL;
12779 }
12780 dev = request->wdev->netdev;
12781#endif
12782
12783 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12784 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
12785 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12786
Jeff Johnson295189b2012-06-20 16:38:30 -070012787 ENTER();
12788
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012789 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12790 __func__, hdd_device_modetoString(pAdapter->device_mode),
12791 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012792
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012793 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012794 if (0 != status)
12795 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012796 return status;
12797 }
12798
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012799 if (NULL == pwextBuf)
12800 {
12801 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
12802 __func__);
12803 return -EIO;
12804 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012805 cfg_param = pHddCtx->cfg_ini;
12806 pScanInfo = &pHddCtx->scan_info;
12807
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053012808 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12809 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
12810 {
12811 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
12812 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
12813 }
12814
Jeff Johnson295189b2012-06-20 16:38:30 -070012815#ifdef WLAN_BTAMP_FEATURE
12816 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012817 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070012818 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080012819 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012820 "%s: No scanning when AMP is on", __func__);
12821 return -EOPNOTSUPP;
12822 }
12823#endif
12824 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012825 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012826 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012827 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012828 "%s: Not scanning on device_mode = %s (%d)",
12829 __func__, hdd_device_modetoString(pAdapter->device_mode),
12830 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012831 return -EOPNOTSUPP;
12832 }
12833
12834 if (TRUE == pScanInfo->mScanPending)
12835 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053012836 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
12837 {
12838 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
12839 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012840 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070012841 }
12842
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053012843 // Don't allow scan if PNO scan is going on.
12844 if (pHddCtx->isPnoEnable)
12845 {
12846 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12847 FL("pno scan in progress"));
12848 return -EBUSY;
12849 }
12850
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012851 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070012852 //Channel and action frame is pending
12853 //Otherwise Cancel Remain On Channel and allow Scan
12854 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012855 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070012856 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053012857 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070012858 return -EBUSY;
12859 }
12860
Jeff Johnson295189b2012-06-20 16:38:30 -070012861 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
12862 {
12863 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080012864 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012865 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012866 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012867 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
12868 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012869 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012870 "%s: MAX TM Level Scan not allowed", __func__);
12871 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012872 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070012873 }
12874 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
12875
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012876 /* Check if scan is allowed at this point of time.
12877 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012878 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012879 {
12880 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
12881 return -EBUSY;
12882 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012883
Jeff Johnson295189b2012-06-20 16:38:30 -070012884 vos_mem_zero( &scanRequest, sizeof(scanRequest));
12885
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012886 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
12887 * Becasue of this, driver is assuming that this is not wildcard scan and so
12888 * is not aging out the scan results.
12889 */
12890 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070012891 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012892 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012893 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012894
12895 if ((request->ssids) && (0 < request->n_ssids))
12896 {
12897 tCsrSSIDInfo *SsidInfo;
12898 int j;
12899 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
12900 /* Allocate num_ssid tCsrSSIDInfo structure */
12901 SsidInfo = scanRequest.SSIDs.SSIDList =
12902 ( tCsrSSIDInfo *)vos_mem_malloc(
12903 request->n_ssids*sizeof(tCsrSSIDInfo));
12904
12905 if(NULL == scanRequest.SSIDs.SSIDList)
12906 {
12907 hddLog(VOS_TRACE_LEVEL_ERROR,
12908 "%s: memory alloc failed SSIDInfo buffer", __func__);
12909 return -ENOMEM;
12910 }
12911
12912 /* copy all the ssid's and their length */
12913 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
12914 {
12915 /* get the ssid length */
12916 SsidInfo->SSID.length = request->ssids[j].ssid_len;
12917 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
12918 SsidInfo->SSID.length);
12919 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
12920 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
12921 j, SsidInfo->SSID.ssId);
12922 }
12923 /* set the scan type to active */
12924 scanRequest.scanType = eSIR_ACTIVE_SCAN;
12925 }
12926 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012927 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012928 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12929 TRACE_CODE_HDD_CFG80211_SCAN,
12930 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070012931 /* set the scan type to active */
12932 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070012933 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012934 else
12935 {
12936 /*Set the scan type to default type, in this case it is ACTIVE*/
12937 scanRequest.scanType = pScanInfo->scan_mode;
12938 }
12939 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
12940 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070012941
12942 /* set BSSType to default type */
12943 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
12944
12945 /*TODO: scan the requested channels only*/
12946
12947 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012948 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070012949 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012950 hddLog(VOS_TRACE_LEVEL_WARN,
12951 "No of Scan Channels exceeded limit: %d", request->n_channels);
12952 request->n_channels = MAX_CHANNEL;
12953 }
12954
12955 hddLog(VOS_TRACE_LEVEL_INFO,
12956 "No of Scan Channels: %d", request->n_channels);
12957
12958
12959 if( request->n_channels )
12960 {
12961 char chList [(request->n_channels*5)+1];
12962 int len;
12963 channelList = vos_mem_malloc( request->n_channels );
12964 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053012965 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012966 hddLog(VOS_TRACE_LEVEL_ERROR,
12967 "%s: memory alloc failed channelList", __func__);
12968 status = -ENOMEM;
12969 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053012970 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012971
12972 for( i = 0, len = 0; i < request->n_channels ; i++ )
12973 {
12974 channelList[i] = request->channels[i]->hw_value;
12975 len += snprintf(chList+len, 5, "%d ", channelList[i]);
12976 }
12977
Nirav Shah20ac06f2013-12-12 18:14:06 +053012978 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012979 "Channel-List: %s ", chList);
12980 }
c_hpothu53512302014-04-15 18:49:53 +053012981
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012982 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
12983 scanRequest.ChannelInfo.ChannelList = channelList;
12984
12985 /* set requestType to full scan */
12986 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
12987
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012988 /* if there is back to back scan happening in driver with in
12989 * nDeferScanTimeInterval interval driver should defer new scan request
12990 * and should provide last cached scan results instead of new channel list.
12991 * This rule is not applicable if scan is p2p scan.
12992 * This condition will work only in case when last request no of channels
12993 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053012994 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053012995 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012996 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012997
Sushant Kaushik86592172015-04-27 16:35:03 +053012998 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
12999 /* if wps ie is NULL , then only defer scan */
13000 if ( pWpsIe == NULL &&
13001 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053013002 {
13003 if ( pScanInfo->last_scan_timestamp !=0 &&
13004 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
13005 {
13006 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
13007 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
13008 vos_mem_compare(pScanInfo->last_scan_channelList,
13009 channelList, pScanInfo->last_scan_numChannels))
13010 {
13011 hddLog(VOS_TRACE_LEVEL_WARN,
13012 " New and old station scan time differ is less then %u",
13013 pHddCtx->cfg_ini->nDeferScanTimeInterval);
13014
13015 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013016 pAdapter);
13017
Agarwal Ashish57e84372014-12-05 18:26:53 +053013018 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013019 "Return old cached scan as all channels and no of channels are same");
13020
Agarwal Ashish57e84372014-12-05 18:26:53 +053013021 if (0 > ret)
13022 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013023
Agarwal Ashish57e84372014-12-05 18:26:53 +053013024 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053013025
13026 status = eHAL_STATUS_SUCCESS;
13027 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053013028 }
13029 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053013030 }
13031
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013032 /* Flush the scan results(only p2p beacons) for STA scan and P2P
13033 * search (Flush on both full scan and social scan but not on single
13034 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
13035 */
13036
13037 /* Supplicant does single channel scan after 8-way handshake
13038 * and in that case driver shoudnt flush scan results. If
13039 * driver flushes the scan results here and unfortunately if
13040 * the AP doesnt respond to our probe req then association
13041 * fails which is not desired
13042 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013043 if ((request->n_ssids == 1)
13044 && (request->ssids != NULL)
13045 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
13046 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013047
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013048 if( is_p2p_scan ||
13049 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013050 {
13051 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
13052 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
13053 pAdapter->sessionId );
13054 }
13055
13056 if( request->ie_len )
13057 {
13058 /* save this for future association (join requires this) */
13059 /*TODO: Array needs to be converted to dynamic allocation,
13060 * as multiple ie.s can be sent in cfg80211_scan_request structure
13061 * CR 597966
13062 */
13063 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
13064 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
13065 pScanInfo->scanAddIE.length = request->ie_len;
13066
13067 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13068 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13069 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013070 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013071 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070013072 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013073 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
13074 memcpy( pwextBuf->roamProfile.addIEScan,
13075 request->ie, request->ie_len);
13076 }
13077 else
13078 {
13079 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
13080 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013081 }
13082
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013083 }
13084 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
13085 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
13086
13087 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
13088 request->ie_len);
13089 if (pP2pIe != NULL)
13090 {
13091#ifdef WLAN_FEATURE_P2P_DEBUG
13092 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
13093 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
13094 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053013095 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013096 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
13097 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13098 "Go nego completed to Connection is started");
13099 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13100 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053013101 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013102 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
13103 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013104 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013105 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
13106 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13107 "Disconnected state to Connection is started");
13108 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13109 "for 4way Handshake");
13110 }
13111#endif
13112
13113 /* no_cck will be set during p2p find to disable 11b rates */
13114 if(TRUE == request->no_cck)
13115 {
13116 hddLog(VOS_TRACE_LEVEL_INFO,
13117 "%s: This is a P2P Search", __func__);
13118 scanRequest.p2pSearch = 1;
13119
13120 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053013121 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013122 /* set requestType to P2P Discovery */
13123 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
13124 }
13125
13126 /*
13127 Skip Dfs Channel in case of P2P Search
13128 if it is set in ini file
13129 */
13130 if(cfg_param->skipDfsChnlInP2pSearch)
13131 {
13132 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013133 }
13134 else
13135 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013136 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013137 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013138
Agarwal Ashish4f616132013-12-30 23:32:50 +053013139 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013140 }
13141 }
13142
13143 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
13144
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013145#ifdef FEATURE_WLAN_TDLS
13146 /* if tdls disagree scan right now, return immediately.
13147 tdls will schedule the scan when scan is allowed. (return SUCCESS)
13148 or will reject the scan if any TDLS is in progress. (return -EBUSY)
13149 */
13150 status = wlan_hdd_tdls_scan_callback (pAdapter,
13151 wiphy,
13152#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13153 dev,
13154#endif
13155 request);
13156 if(status <= 0)
13157 {
13158 if(!status)
13159 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
13160 "scan rejected %d", __func__, status);
13161 else
13162 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
13163 __func__, status);
13164
13165 return status;
13166 }
13167#endif
13168
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013169 /* acquire the wakelock to avoid the apps suspend during the scan. To
13170 * address the following issues.
13171 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
13172 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
13173 * for long time, this result in apps running at full power for long time.
13174 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
13175 * be stuck in full power because of resume BMPS
13176 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013177 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013178
Nirav Shah20ac06f2013-12-12 18:14:06 +053013179 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
13180 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013181 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
13182 scanRequest.requestType, scanRequest.scanType,
13183 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053013184 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
13185
Siddharth Bhal76972212014-10-15 16:22:51 +053013186 if (pHddCtx->spoofMacAddr.isEnabled)
13187 {
13188 hddLog(VOS_TRACE_LEVEL_INFO,
13189 "%s: MAC Spoofing enabled for current scan", __func__);
13190 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
13191 * to fill TxBds for probe request during current scan
13192 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013193 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053013194 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013195
13196 if(status != VOS_STATUS_SUCCESS)
13197 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013198 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013199 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053013200#ifdef FEATURE_WLAN_TDLS
13201 wlan_hdd_tdls_scan_done_callback(pAdapter);
13202#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013203 goto free_mem;
13204 }
Siddharth Bhal76972212014-10-15 16:22:51 +053013205 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013206 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070013207 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013208 pAdapter->sessionId, &scanRequest, &scanId,
13209 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070013210
Jeff Johnson295189b2012-06-20 16:38:30 -070013211 if (eHAL_STATUS_SUCCESS != status)
13212 {
13213 hddLog(VOS_TRACE_LEVEL_ERROR,
13214 "%s: sme_ScanRequest returned error %d", __func__, status);
13215 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013216 if(eHAL_STATUS_RESOURCES == status)
13217 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013218 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
13219 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013220 status = -EBUSY;
13221 } else {
13222 status = -EIO;
13223 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013224 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013225
13226#ifdef FEATURE_WLAN_TDLS
13227 wlan_hdd_tdls_scan_done_callback(pAdapter);
13228#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013229 goto free_mem;
13230 }
13231
13232 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013233 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070013234 pAdapter->request = request;
13235 pScanInfo->scanId = scanId;
13236
13237 complete(&pScanInfo->scan_req_completion_event);
13238
13239free_mem:
13240 if( scanRequest.SSIDs.SSIDList )
13241 {
13242 vos_mem_free(scanRequest.SSIDs.SSIDList);
13243 }
13244
13245 if( channelList )
13246 vos_mem_free( channelList );
13247
13248 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013249 return status;
13250}
13251
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013252int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
13253#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13254 struct net_device *dev,
13255#endif
13256 struct cfg80211_scan_request *request)
13257{
13258 int ret;
13259
13260 vos_ssr_protect(__func__);
13261 ret = __wlan_hdd_cfg80211_scan(wiphy,
13262#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13263 dev,
13264#endif
13265 request);
13266 vos_ssr_unprotect(__func__);
13267
13268 return ret;
13269}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013270
13271void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
13272{
13273 v_U8_t iniDot11Mode =
13274 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
13275 eHddDot11Mode hddDot11Mode = iniDot11Mode;
13276
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013277 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
13278 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013279 switch ( iniDot11Mode )
13280 {
13281 case eHDD_DOT11_MODE_AUTO:
13282 case eHDD_DOT11_MODE_11ac:
13283 case eHDD_DOT11_MODE_11ac_ONLY:
13284#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053013285 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
13286 sme_IsFeatureSupportedByFW(DOT11AC) )
13287 hddDot11Mode = eHDD_DOT11_MODE_11ac;
13288 else
13289 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013290#else
13291 hddDot11Mode = eHDD_DOT11_MODE_11n;
13292#endif
13293 break;
13294 case eHDD_DOT11_MODE_11n:
13295 case eHDD_DOT11_MODE_11n_ONLY:
13296 hddDot11Mode = eHDD_DOT11_MODE_11n;
13297 break;
13298 default:
13299 hddDot11Mode = iniDot11Mode;
13300 break;
13301 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013302#ifdef WLAN_FEATURE_AP_HT40_24G
13303 if (operationChannel > SIR_11B_CHANNEL_END)
13304#endif
13305 {
13306 /* This call decides required channel bonding mode */
13307 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013308 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
13309 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013310 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013311}
13312
Jeff Johnson295189b2012-06-20 16:38:30 -070013313/*
13314 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013315 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070013316 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013317int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013318 const u8 *ssid, size_t ssid_len, const u8 *bssid,
13319 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070013320{
13321 int status = 0;
13322 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080013323 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013324 v_U32_t roamId;
13325 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070013326 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013327 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013328
13329 ENTER();
13330
13331 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080013332 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13333
13334 status = wlan_hdd_validate_context(pHddCtx);
13335 if (status)
13336 {
Yue Mae36e3552014-03-05 17:06:20 -080013337 return status;
13338 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013339
Jeff Johnson295189b2012-06-20 16:38:30 -070013340 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
13341 {
13342 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
13343 return -EINVAL;
13344 }
13345
13346 pRoamProfile = &pWextState->roamProfile;
13347
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013348 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070013349 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013350 hdd_station_ctx_t *pHddStaCtx;
13351 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013352
Siddharth Bhalda0d1622015-04-24 15:47:49 +053013353 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
13354
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013355 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070013356 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
13357 {
13358 /*QoS not enabled in cfg file*/
13359 pRoamProfile->uapsd_mask = 0;
13360 }
13361 else
13362 {
13363 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013364 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070013365 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
13366 }
13367
13368 pRoamProfile->SSIDs.numOfSSIDs = 1;
13369 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
13370 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013371 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070013372 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
13373 ssid, ssid_len);
13374
13375 if (bssid)
13376 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013377 pValidBssid = bssid;
13378 }
13379 else if (bssid_hint)
13380 {
13381 pValidBssid = bssid_hint;
13382 }
13383 if (pValidBssid)
13384 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013385 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013386 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013387 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013388 /* Save BSSID in seperate variable as well, as RoamProfile
13389 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070013390 case of join failure we should send valid BSSID to supplicant
13391 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013392 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013393 WNI_CFG_BSSID_LEN);
13394 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070013395 else
13396 {
13397 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
13398 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013399
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013400 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
13401 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013402 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
13403 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013404 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013405 /*set gen ie*/
13406 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
13407 /*set auth*/
13408 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
13409 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013410#ifdef FEATURE_WLAN_WAPI
13411 if (pAdapter->wapi_info.nWapiMode)
13412 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013413 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013414 switch (pAdapter->wapi_info.wapiAuthMode)
13415 {
13416 case WAPI_AUTH_MODE_PSK:
13417 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013418 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013419 pAdapter->wapi_info.wapiAuthMode);
13420 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
13421 break;
13422 }
13423 case WAPI_AUTH_MODE_CERT:
13424 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013425 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013426 pAdapter->wapi_info.wapiAuthMode);
13427 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
13428 break;
13429 }
13430 } // End of switch
13431 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
13432 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
13433 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013434 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013435 pRoamProfile->AuthType.numEntries = 1;
13436 pRoamProfile->EncryptionType.numEntries = 1;
13437 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13438 pRoamProfile->mcEncryptionType.numEntries = 1;
13439 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13440 }
13441 }
13442#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013443#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013444 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013445 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13446 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
13447 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013448 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
13449 sizeof (tSirGtkOffloadParams));
13450 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013451 }
13452#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013453 pRoamProfile->csrPersona = pAdapter->device_mode;
13454
Jeff Johnson32d95a32012-09-10 13:15:23 -070013455 if( operatingChannel )
13456 {
13457 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
13458 pRoamProfile->ChannelInfo.numOfChannels = 1;
13459 }
Chet Lanctot186b5732013-03-18 10:26:30 -070013460 else
13461 {
13462 pRoamProfile->ChannelInfo.ChannelList = NULL;
13463 pRoamProfile->ChannelInfo.numOfChannels = 0;
13464 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013465 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
13466 {
13467 hdd_select_cbmode(pAdapter,operatingChannel);
13468 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013469
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013470 /*
13471 * Change conn_state to connecting before sme_RoamConnect(),
13472 * because sme_RoamConnect() has a direct path to call
13473 * hdd_smeRoamCallback(), which will change the conn_state
13474 * If direct path, conn_state will be accordingly changed
13475 * to NotConnected or Associated by either
13476 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
13477 * in sme_RoamCallback()
13478 * if sme_RomConnect is to be queued,
13479 * Connecting state will remain until it is completed.
13480 * If connection state is not changed,
13481 * connection state will remain in eConnectionState_NotConnected state.
13482 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
13483 * if conn state is eConnectionState_NotConnected.
13484 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
13485 * informed of connect result indication which is an issue.
13486 */
13487
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013488 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13489 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053013490 {
13491 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013492 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013493 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
13494 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053013495 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013496 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013497 pAdapter->sessionId, pRoamProfile, &roamId);
13498
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013499 if ((eHAL_STATUS_SUCCESS != status) &&
13500 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13501 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013502
13503 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013504 hddLog(VOS_TRACE_LEVEL_ERROR,
13505 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
13506 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013507 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013508 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013509 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013510 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013511
13512 pRoamProfile->ChannelInfo.ChannelList = NULL;
13513 pRoamProfile->ChannelInfo.numOfChannels = 0;
13514
Jeff Johnson295189b2012-06-20 16:38:30 -070013515 }
13516 else
13517 {
13518 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
13519 return -EINVAL;
13520 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013521 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013522 return status;
13523}
13524
13525/*
13526 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
13527 * This function is used to set the authentication type (OPEN/SHARED).
13528 *
13529 */
13530static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
13531 enum nl80211_auth_type auth_type)
13532{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013533 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013534 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13535
13536 ENTER();
13537
13538 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013539 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070013540 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013541 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013542 hddLog(VOS_TRACE_LEVEL_INFO,
13543 "%s: set authentication type to AUTOSWITCH", __func__);
13544 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
13545 break;
13546
13547 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013548#ifdef WLAN_FEATURE_VOWIFI_11R
13549 case NL80211_AUTHTYPE_FT:
13550#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013551 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013552 "%s: set authentication type to OPEN", __func__);
13553 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
13554 break;
13555
13556 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013557 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013558 "%s: set authentication type to SHARED", __func__);
13559 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
13560 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013561#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013562 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013563 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013564 "%s: set authentication type to CCKM WPA", __func__);
13565 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
13566 break;
13567#endif
13568
13569
13570 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013571 hddLog(VOS_TRACE_LEVEL_ERROR,
13572 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013573 auth_type);
13574 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
13575 return -EINVAL;
13576 }
13577
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013578 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013579 pHddStaCtx->conn_info.authType;
13580 return 0;
13581}
13582
13583/*
13584 * FUNCTION: wlan_hdd_set_akm_suite
13585 * This function is used to set the key mgmt type(PSK/8021x).
13586 *
13587 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013588static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013589 u32 key_mgmt
13590 )
13591{
13592 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13593 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053013594 /* Should be in ieee802_11_defs.h */
13595#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
13596#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070013597 /*set key mgmt type*/
13598 switch(key_mgmt)
13599 {
13600 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053013601 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013602#ifdef WLAN_FEATURE_VOWIFI_11R
13603 case WLAN_AKM_SUITE_FT_PSK:
13604#endif
13605 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070013606 __func__);
13607 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
13608 break;
13609
13610 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053013611 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013612#ifdef WLAN_FEATURE_VOWIFI_11R
13613 case WLAN_AKM_SUITE_FT_8021X:
13614#endif
13615 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070013616 __func__);
13617 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13618 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013619#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013620#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
13621#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
13622 case WLAN_AKM_SUITE_CCKM:
13623 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
13624 __func__);
13625 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
13626 break;
13627#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070013628#ifndef WLAN_AKM_SUITE_OSEN
13629#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
13630 case WLAN_AKM_SUITE_OSEN:
13631 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
13632 __func__);
13633 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13634 break;
13635#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013636
13637 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013638 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013639 __func__, key_mgmt);
13640 return -EINVAL;
13641
13642 }
13643 return 0;
13644}
13645
13646/*
13647 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013648 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070013649 * (NONE/WEP40/WEP104/TKIP/CCMP).
13650 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013651static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
13652 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070013653 bool ucast
13654 )
13655{
13656 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013657 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013658 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13659
13660 ENTER();
13661
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013662 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013663 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013664 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070013665 __func__, cipher);
13666 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13667 }
13668 else
13669 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013670
Jeff Johnson295189b2012-06-20 16:38:30 -070013671 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013672 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013673 {
13674 case IW_AUTH_CIPHER_NONE:
13675 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13676 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013677
Jeff Johnson295189b2012-06-20 16:38:30 -070013678 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013679 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070013680 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013681
Jeff Johnson295189b2012-06-20 16:38:30 -070013682 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013683 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070013684 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013685
Jeff Johnson295189b2012-06-20 16:38:30 -070013686 case WLAN_CIPHER_SUITE_TKIP:
13687 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
13688 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013689
Jeff Johnson295189b2012-06-20 16:38:30 -070013690 case WLAN_CIPHER_SUITE_CCMP:
13691 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13692 break;
13693#ifdef FEATURE_WLAN_WAPI
13694 case WLAN_CIPHER_SUITE_SMS4:
13695 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
13696 break;
13697#endif
13698
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013699#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013700 case WLAN_CIPHER_SUITE_KRK:
13701 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
13702 break;
13703#endif
13704 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013705 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013706 __func__, cipher);
13707 return -EOPNOTSUPP;
13708 }
13709 }
13710
13711 if (ucast)
13712 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013713 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013714 __func__, encryptionType);
13715 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13716 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013717 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013718 encryptionType;
13719 }
13720 else
13721 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013722 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013723 __func__, encryptionType);
13724 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
13725 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
13726 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
13727 }
13728
13729 return 0;
13730}
13731
13732
13733/*
13734 * FUNCTION: wlan_hdd_cfg80211_set_ie
13735 * This function is used to parse WPA/RSN IE's.
13736 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013737int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013738#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13739 const u8 *ie,
13740#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013741 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013742#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013743 size_t ie_len
13744 )
13745{
13746 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013747#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13748 const u8 *genie = ie;
13749#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013750 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013751#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013752 v_U16_t remLen = ie_len;
13753#ifdef FEATURE_WLAN_WAPI
13754 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
13755 u16 *tmp;
13756 v_U16_t akmsuiteCount;
13757 int *akmlist;
13758#endif
13759 ENTER();
13760
13761 /* clear previous assocAddIE */
13762 pWextState->assocAddIE.length = 0;
13763 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013764 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013765
13766 while (remLen >= 2)
13767 {
13768 v_U16_t eLen = 0;
13769 v_U8_t elementId;
13770 elementId = *genie++;
13771 eLen = *genie++;
13772 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013773
Arif Hussain6d2a3322013-11-17 19:50:10 -080013774 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070013775 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013776
13777 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070013778 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013779 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013780 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 -070013781 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013782 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013783 "%s: Invalid WPA IE", __func__);
13784 return -EINVAL;
13785 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013786 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070013787 {
13788 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013789 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013790 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013791
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013792 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013793 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013794 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
13795 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013796 VOS_ASSERT(0);
13797 return -ENOMEM;
13798 }
13799 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
13800 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13801 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013802
Jeff Johnson295189b2012-06-20 16:38:30 -070013803 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
13804 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13805 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13806 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013807 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
13808 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013809 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
13810 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
13811 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
13812 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
13813 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
13814 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013815 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053013816 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013817 {
13818 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013819 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013820 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013821
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013822 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013823 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013824 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13825 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013826 VOS_ASSERT(0);
13827 return -ENOMEM;
13828 }
13829 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
13830 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13831 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013832
Jeff Johnson295189b2012-06-20 16:38:30 -070013833 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13834 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13835 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013836#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013837 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
13838 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013839 /*Consider WFD IE, only for P2P Client */
13840 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
13841 {
13842 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013843 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013844 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013845
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013846 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013847 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013848 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13849 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013850 VOS_ASSERT(0);
13851 return -ENOMEM;
13852 }
13853 // WFD IE is saved to Additional IE ; it should be accumulated to handle
13854 // WPS IE + P2P IE + WFD IE
13855 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13856 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013857
Jeff Johnson295189b2012-06-20 16:38:30 -070013858 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13859 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13860 }
13861#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013862 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013863 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013864 HS20_OUI_TYPE_SIZE)) )
13865 {
13866 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013867 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013868 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013869
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013870 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013871 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013872 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13873 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013874 VOS_ASSERT(0);
13875 return -ENOMEM;
13876 }
13877 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13878 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013879
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013880 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13881 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13882 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013883 /* Appending OSEN Information Element in Assiciation Request */
13884 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
13885 OSEN_OUI_TYPE_SIZE)) )
13886 {
13887 v_U16_t curAddIELen = pWextState->assocAddIE.length;
13888 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
13889 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013890
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013891 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013892 {
13893 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13894 "Need bigger buffer space");
13895 VOS_ASSERT(0);
13896 return -ENOMEM;
13897 }
13898 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13899 pWextState->assocAddIE.length += eLen + 2;
13900
13901 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
13902 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13903 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13904 }
13905
Abhishek Singh4322e622015-06-10 15:42:54 +053013906 /* Update only for WPA IE */
13907 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
13908 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070013909
13910 /* populating as ADDIE in beacon frames */
13911 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013912 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070013913 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
13914 {
13915 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
13916 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
13917 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
13918 {
13919 hddLog(LOGE,
13920 "Coldn't pass "
13921 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
13922 }
13923 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
13924 else
13925 hddLog(LOGE,
13926 "Could not pass on "
13927 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
13928
13929 /* IBSS mode doesn't contain params->proberesp_ies still
13930 beaconIE's need to be populated in probe response frames */
13931 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
13932 {
13933 u16 rem_probe_resp_ie_len = eLen + 2;
13934 u8 probe_rsp_ie_len[3] = {0};
13935 u8 counter = 0;
13936
13937 /* Check Probe Resp Length if it is greater then 255 then
13938 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
13939 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
13940 not able Store More then 255 bytes into One Variable */
13941
13942 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
13943 {
13944 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
13945 {
13946 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
13947 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
13948 }
13949 else
13950 {
13951 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
13952 rem_probe_resp_ie_len = 0;
13953 }
13954 }
13955
13956 rem_probe_resp_ie_len = 0;
13957
13958 if (probe_rsp_ie_len[0] > 0)
13959 {
13960 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
13961 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
13962 (tANI_U8*)(genie - 2),
13963 probe_rsp_ie_len[0], NULL,
13964 eANI_BOOLEAN_FALSE)
13965 == eHAL_STATUS_FAILURE)
13966 {
13967 hddLog(LOGE,
13968 "Could not pass"
13969 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
13970 }
13971 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
13972 }
13973
13974 if (probe_rsp_ie_len[1] > 0)
13975 {
13976 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
13977 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
13978 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
13979 probe_rsp_ie_len[1], NULL,
13980 eANI_BOOLEAN_FALSE)
13981 == eHAL_STATUS_FAILURE)
13982 {
13983 hddLog(LOGE,
13984 "Could not pass"
13985 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
13986 }
13987 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
13988 }
13989
13990 if (probe_rsp_ie_len[2] > 0)
13991 {
13992 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
13993 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
13994 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
13995 probe_rsp_ie_len[2], NULL,
13996 eANI_BOOLEAN_FALSE)
13997 == eHAL_STATUS_FAILURE)
13998 {
13999 hddLog(LOGE,
14000 "Could not pass"
14001 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
14002 }
14003 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
14004 }
14005
14006 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
14007 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
14008 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
14009 {
14010 hddLog(LOGE,
14011 "Could not pass"
14012 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
14013 }
14014 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070014015 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070014016 break;
14017 case DOT11F_EID_RSN:
14018 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
14019 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
14020 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
14021 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
14022 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
14023 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053014024
14025 /* Appending Extended Capabilities with Interworking bit set
14026 * in Assoc Req.
14027 *
14028 * In assoc req this EXT Cap will only be taken into account if
14029 * interworkingService bit is set to 1. Currently
14030 * driver is only interested in interworkingService capability
14031 * from supplicant. If in future any other EXT Cap info is
14032 * required from supplicat, it needs to be handled while
14033 * sending Assoc Req in LIM.
14034 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014035 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014036 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014037 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014038 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014039 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014040
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014041 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014042 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014043 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14044 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014045 VOS_ASSERT(0);
14046 return -ENOMEM;
14047 }
14048 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14049 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014050
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014051 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14052 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14053 break;
14054 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014055#ifdef FEATURE_WLAN_WAPI
14056 case WLAN_EID_WAPI:
14057 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014058 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070014059 pAdapter->wapi_info.nWapiMode);
14060 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014061 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070014062 akmsuiteCount = WPA_GET_LE16(tmp);
14063 tmp = tmp + 1;
14064 akmlist = (int *)(tmp);
14065 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
14066 {
14067 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
14068 }
14069 else
14070 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014071 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070014072 VOS_ASSERT(0);
14073 return -EINVAL;
14074 }
14075
14076 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
14077 {
14078 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014079 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014080 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014081 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014082 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014083 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014084 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014085 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014086 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
14087 }
14088 break;
14089#endif
14090 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014091 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014092 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014093 /* when Unknown IE is received we should break and continue
14094 * to the next IE in the buffer instead we were returning
14095 * so changing this to break */
14096 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070014097 }
14098 genie += eLen;
14099 remLen -= eLen;
14100 }
14101 EXIT();
14102 return 0;
14103}
14104
14105/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014106 * FUNCTION: hdd_isWPAIEPresent
14107 * Parse the received IE to find the WPA IE
14108 *
14109 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014110static bool hdd_isWPAIEPresent(
14111#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
14112 const u8 *ie,
14113#else
14114 u8 *ie,
14115#endif
14116 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014117{
14118 v_U8_t eLen = 0;
14119 v_U16_t remLen = ie_len;
14120 v_U8_t elementId = 0;
14121
14122 while (remLen >= 2)
14123 {
14124 elementId = *ie++;
14125 eLen = *ie++;
14126 remLen -= 2;
14127 if (eLen > remLen)
14128 {
14129 hddLog(VOS_TRACE_LEVEL_ERROR,
14130 "%s: IE length is wrong %d", __func__, eLen);
14131 return FALSE;
14132 }
14133 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
14134 {
14135 /* OUI - 0x00 0X50 0XF2
14136 WPA Information Element - 0x01
14137 WPA version - 0x01*/
14138 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
14139 return TRUE;
14140 }
14141 ie += eLen;
14142 remLen -= eLen;
14143 }
14144 return FALSE;
14145}
14146
14147/*
Jeff Johnson295189b2012-06-20 16:38:30 -070014148 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014149 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014150 * parameters during connect operation.
14151 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014152int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014153 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014154 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014155{
14156 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014157 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014158 ENTER();
14159
14160 /*set wpa version*/
14161 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
14162
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014163 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014164 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053014165 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014166 {
14167 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14168 }
14169 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
14170 {
14171 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14172 }
14173 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014174
14175 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014176 pWextState->wpaVersion);
14177
14178 /*set authentication type*/
14179 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
14180
14181 if (0 > status)
14182 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014183 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014184 "%s: failed to set authentication type ", __func__);
14185 return status;
14186 }
14187
14188 /*set key mgmt type*/
14189 if (req->crypto.n_akm_suites)
14190 {
14191 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
14192 if (0 > status)
14193 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014194 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070014195 __func__);
14196 return status;
14197 }
14198 }
14199
14200 /*set pairwise cipher type*/
14201 if (req->crypto.n_ciphers_pairwise)
14202 {
14203 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
14204 req->crypto.ciphers_pairwise[0], true);
14205 if (0 > status)
14206 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014207 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014208 "%s: failed to set unicast cipher type", __func__);
14209 return status;
14210 }
14211 }
14212 else
14213 {
14214 /*Reset previous cipher suite to none*/
14215 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
14216 if (0 > status)
14217 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014218 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014219 "%s: failed to set unicast cipher type", __func__);
14220 return status;
14221 }
14222 }
14223
14224 /*set group cipher type*/
14225 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
14226 false);
14227
14228 if (0 > status)
14229 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014230 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070014231 __func__);
14232 return status;
14233 }
14234
Chet Lanctot186b5732013-03-18 10:26:30 -070014235#ifdef WLAN_FEATURE_11W
14236 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
14237#endif
14238
Jeff Johnson295189b2012-06-20 16:38:30 -070014239 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
14240 if (req->ie_len)
14241 {
14242 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
14243 if ( 0 > status)
14244 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014245 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014246 __func__);
14247 return status;
14248 }
14249 }
14250
14251 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014252 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014253 {
14254 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
14255 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
14256 )
14257 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014258 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070014259 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
14260 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014261 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070014262 __func__);
14263 return -EOPNOTSUPP;
14264 }
14265 else
14266 {
14267 u8 key_len = req->key_len;
14268 u8 key_idx = req->key_idx;
14269
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014270 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014271 && (CSR_MAX_NUM_KEY > key_idx)
14272 )
14273 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014274 hddLog(VOS_TRACE_LEVEL_INFO,
14275 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014276 __func__, key_idx, key_len);
14277 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014278 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014279 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014280 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014281 (u8)key_len;
14282 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
14283 }
14284 }
14285 }
14286 }
14287
14288 return status;
14289}
14290
14291/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014292 * FUNCTION: wlan_hdd_try_disconnect
14293 * This function is used to disconnect from previous
14294 * connection
14295 */
14296static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
14297{
14298 long ret = 0;
14299 hdd_station_ctx_t *pHddStaCtx;
14300 eMib_dot11DesiredBssType connectedBssType;
14301
14302 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14303
14304 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
14305
14306 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
14307 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
14308 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
14309 {
Abhishek Singhf7962582015-10-23 10:54:06 +053014310 hdd_connSetConnectionState(pHddStaCtx,
14311 eConnectionState_Disconnecting);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014312 /* Issue disconnect to CSR */
14313 INIT_COMPLETION(pAdapter->disconnect_comp_var);
14314 if( eHAL_STATUS_SUCCESS ==
14315 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
14316 pAdapter->sessionId,
14317 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
14318 {
14319 ret = wait_for_completion_interruptible_timeout(
14320 &pAdapter->disconnect_comp_var,
14321 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
14322 if (0 >= ret)
14323 {
14324 hddLog(LOGE, FL("Failed to receive disconnect event"));
14325 return -EALREADY;
14326 }
14327 }
14328 }
14329 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
14330 {
14331 ret = wait_for_completion_interruptible_timeout(
14332 &pAdapter->disconnect_comp_var,
14333 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
14334 if (0 >= ret)
14335 {
14336 hddLog(LOGE, FL("Failed to receive disconnect event"));
14337 return -EALREADY;
14338 }
14339 }
14340
14341 return 0;
14342}
14343
14344/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053014345 * FUNCTION: __wlan_hdd_cfg80211_connect
14346 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014347 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014348static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014349 struct net_device *ndev,
14350 struct cfg80211_connect_params *req
14351 )
14352{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014353 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014354 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014355 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053014356 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014357
14358 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014359
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014360 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14361 TRACE_CODE_HDD_CFG80211_CONNECT,
14362 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014363 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014364 "%s: device_mode = %s (%d)", __func__,
14365 hdd_device_modetoString(pAdapter->device_mode),
14366 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014367
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014368 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014369 if (!pHddCtx)
14370 {
14371 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14372 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053014373 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014374 }
14375
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014376 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014377 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014378 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014379 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014380 }
14381
Agarwal Ashish51325b52014-06-16 16:50:49 +053014382 if (vos_max_concurrent_connections_reached()) {
14383 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14384 return -ECONNREFUSED;
14385 }
14386
Jeff Johnson295189b2012-06-20 16:38:30 -070014387#ifdef WLAN_BTAMP_FEATURE
14388 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014389 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070014390 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014391 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014392 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014393 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070014394 }
14395#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014396
14397 //If Device Mode is Station Concurrent Sessions Exit BMps
14398 //P2P Mode will be taken care in Open/close adapter
14399 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053014400 (vos_concurrent_open_sessions_running())) {
14401 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
14402 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014403 }
14404
14405 /*Try disconnecting if already in connected state*/
14406 status = wlan_hdd_try_disconnect(pAdapter);
14407 if ( 0 > status)
14408 {
14409 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14410 " connection"));
14411 return -EALREADY;
14412 }
14413
Jeff Johnson295189b2012-06-20 16:38:30 -070014414 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014415 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070014416
14417 if ( 0 > status)
14418 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014419 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070014420 __func__);
14421 return status;
14422 }
Mohit Khanna765234a2012-09-11 15:08:35 -070014423 if ( req->channel )
14424 {
14425 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
14426 req->ssid_len, req->bssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014427 req->bssid_hint,
Mohit Khanna765234a2012-09-11 15:08:35 -070014428 req->channel->hw_value);
14429 }
14430 else
14431 {
14432 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014433 req->ssid_len, req->bssid,
14434 req->bssid_hint, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070014435 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014436
Sushant Kaushikd7083982015-03-18 14:33:24 +053014437 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014438 {
14439 //ReEnable BMPS if disabled
14440 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
14441 (NULL != pHddCtx))
14442 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053014443 if (pHddCtx->hdd_wlan_suspended)
14444 {
14445 hdd_set_pwrparams(pHddCtx);
14446 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014447 //ReEnable Bmps and Imps back
14448 hdd_enable_bmps_imps(pHddCtx);
14449 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053014450 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070014451 return status;
14452 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014453 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014454 EXIT();
14455 return status;
14456}
14457
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014458static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
14459 struct net_device *ndev,
14460 struct cfg80211_connect_params *req)
14461{
14462 int ret;
14463 vos_ssr_protect(__func__);
14464 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
14465 vos_ssr_unprotect(__func__);
14466
14467 return ret;
14468}
Jeff Johnson295189b2012-06-20 16:38:30 -070014469
14470/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014471 * FUNCTION: wlan_hdd_disconnect
14472 * This function is used to issue a disconnect request to SME
14473 */
14474int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
14475{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014476 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014477 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014478 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014479 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014480
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014481 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014482
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014483 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014484 if (0 != status)
14485 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014486 return status;
14487 }
14488
Sushant Kaushikb4834d22015-07-15 15:29:05 +053014489 if (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)
14490 {
14491 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
14492 pAdapter->sessionId);
14493 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014494 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014495
Agarwal Ashish47d18112014-08-04 19:55:07 +053014496 /* Need to apply spin lock before decreasing active sessions
14497 * as there can be chance for double decrement if context switch
14498 * Calls hdd_DisConnectHandler.
14499 */
14500
14501 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014502 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14503 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014504 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14505 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053014506 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
14507 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014508
Abhishek Singhf4669da2014-05-26 15:07:49 +053014509 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053014510 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
14511
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014512 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014513
Mihir Shete182a0b22014-08-18 16:08:48 +053014514 /*
14515 * stop tx queues before deleting STA/BSS context from the firmware.
14516 * tx has to be disabled because the firmware can get busy dropping
14517 * the tx frames after BSS/STA has been deleted and will not send
14518 * back a response resulting in WDI timeout
14519 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053014520 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053014521 netif_tx_disable(pAdapter->dev);
14522 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014523
Mihir Shete182a0b22014-08-18 16:08:48 +053014524 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014525 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
14526 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014527 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
14528 {
14529 hddLog(VOS_TRACE_LEVEL_INFO,
14530 FL("status = %d, already disconnected"),
14531 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014532
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014533 }
14534 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014535 {
14536 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014537 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014538 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014539 result = -EINVAL;
14540 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014541 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014542 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014543 &pAdapter->disconnect_comp_var,
14544 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014545 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014546 {
14547 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014548 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014549 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014550 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014551 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014552 {
14553 hddLog(VOS_TRACE_LEVEL_ERROR,
14554 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014555 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014556 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014557disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014558 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14559 FL("Set HDD connState to eConnectionState_NotConnected"));
14560 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
14561
Abhishek Singh087de602015-10-21 17:18:55 +053014562#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)
14563 /* Sending disconnect event to userspace for kernel version < 3.11
14564 * is handled by __cfg80211_disconnect call to __cfg80211_disconnected
14565 */
14566 hddLog(LOG1, FL("Send disconnected event to userspace"));
14567 cfg80211_disconnected(pAdapter->dev, WLAN_REASON_UNSPECIFIED,
14568 NULL, 0, GFP_KERNEL);
14569#endif
14570
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014571 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014572 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014573}
14574
14575
14576/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014577 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070014578 * This function is used to issue a disconnect request to SME
14579 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014580static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014581 struct net_device *dev,
14582 u16 reason
14583 )
14584{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014585 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014586 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014587 tCsrRoamProfile *pRoamProfile;
14588 hdd_station_ctx_t *pHddStaCtx;
14589 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014590#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014591 tANI_U8 staIdx;
14592#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014593
Jeff Johnson295189b2012-06-20 16:38:30 -070014594 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014595
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014596 if (!pAdapter) {
14597 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
14598 return -EINVAL;
14599 }
14600
14601 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14602 if (!pHddStaCtx) {
14603 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
14604 return -EINVAL;
14605 }
14606
14607 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14608 status = wlan_hdd_validate_context(pHddCtx);
14609 if (0 != status)
14610 {
14611 return status;
14612 }
14613
14614 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
14615
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014616 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14617 TRACE_CODE_HDD_CFG80211_DISCONNECT,
14618 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014619 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
14620 __func__, hdd_device_modetoString(pAdapter->device_mode),
14621 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014622
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014623 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
14624 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070014625
Jeff Johnson295189b2012-06-20 16:38:30 -070014626 if (NULL != pRoamProfile)
14627 {
14628 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014629 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
14630 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070014631 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014632 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070014633 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014634 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014635 switch(reason)
14636 {
14637 case WLAN_REASON_MIC_FAILURE:
14638 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
14639 break;
14640
14641 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
14642 case WLAN_REASON_DISASSOC_AP_BUSY:
14643 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
14644 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
14645 break;
14646
14647 case WLAN_REASON_PREV_AUTH_NOT_VALID:
14648 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053014649 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070014650 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
14651 break;
14652
Jeff Johnson295189b2012-06-20 16:38:30 -070014653 default:
14654 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
14655 break;
14656 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014657 pScanInfo = &pHddCtx->scan_info;
14658 if (pScanInfo->mScanPending)
14659 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014660 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014661 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014662 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014663 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014664 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053014665 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014666#ifdef FEATURE_WLAN_TDLS
14667 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014668 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014669 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014670 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
14671 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014672 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014673 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014674 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014675 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014676 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014677 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014678 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014679 status = sme_DeleteTdlsPeerSta(
14680 WLAN_HDD_GET_HAL_CTX(pAdapter),
14681 pAdapter->sessionId,
14682 mac);
14683 if (status != eHAL_STATUS_SUCCESS) {
14684 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
14685 return -EPERM;
14686 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014687 }
14688 }
14689#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014690 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014691 status = wlan_hdd_disconnect(pAdapter, reasonCode);
14692 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070014693 {
14694 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014695 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014696 __func__, (int)status );
14697 return -EINVAL;
14698 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014699 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014700 else
14701 {
14702 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
14703 "called while in %d state", __func__,
14704 pHddStaCtx->conn_info.connState);
14705 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014706 }
14707 else
14708 {
14709 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
14710 }
14711
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014712 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014713 return status;
14714}
14715
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014716static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
14717 struct net_device *dev,
14718 u16 reason
14719 )
14720{
14721 int ret;
14722 vos_ssr_protect(__func__);
14723 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
14724 vos_ssr_unprotect(__func__);
14725
14726 return ret;
14727}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014728
Jeff Johnson295189b2012-06-20 16:38:30 -070014729/*
14730 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014731 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014732 * settings in IBSS mode.
14733 */
14734static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014735 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014736 struct cfg80211_ibss_params *params
14737 )
14738{
14739 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014740 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014741 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14742 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014743
Jeff Johnson295189b2012-06-20 16:38:30 -070014744 ENTER();
14745
14746 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070014747 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070014748
14749 if (params->ie_len && ( NULL != params->ie) )
14750 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014751 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
14752 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070014753 {
14754 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14755 encryptionType = eCSR_ENCRYPT_TYPE_AES;
14756 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014757 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070014758 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014759 tDot11fIEWPA dot11WPAIE;
14760 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014761 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014762
Wilson Yang00256342013-10-10 23:13:38 -070014763 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014764 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
14765 params->ie_len, DOT11F_EID_WPA);
14766 if ( NULL != ie )
14767 {
14768 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14769 // Unpack the WPA IE
14770 //Skip past the EID byte and length byte - and four byte WiFi OUI
14771 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
14772 &ie[2+4],
14773 ie[1] - 4,
14774 &dot11WPAIE);
14775 /*Extract the multicast cipher, the encType for unicast
14776 cipher for wpa-none is none*/
14777 encryptionType =
14778 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
14779 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014780 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014781
Jeff Johnson295189b2012-06-20 16:38:30 -070014782 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
14783
14784 if (0 > status)
14785 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014786 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014787 __func__);
14788 return status;
14789 }
14790 }
14791
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014792 pWextState->roamProfile.AuthType.authType[0] =
14793 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070014794 eCSR_AUTH_TYPE_OPEN_SYSTEM;
14795
14796 if (params->privacy)
14797 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014798 /* Security enabled IBSS, At this time there is no information available
14799 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070014800 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014801 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070014802 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014803 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070014804 *enable privacy bit in beacons */
14805
14806 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
14807 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014808 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
14809 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070014810 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
14811 pWextState->roamProfile.EncryptionType.numEntries = 1;
14812 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070014813 return status;
14814}
14815
14816/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014817 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014818 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070014819 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014820static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014821 struct net_device *dev,
14822 struct cfg80211_ibss_params *params
14823 )
14824{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014825 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014826 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14827 tCsrRoamProfile *pRoamProfile;
14828 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014829 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14830 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014831 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070014832
14833 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014834
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014835 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14836 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
14837 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014838 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014839 "%s: device_mode = %s (%d)", __func__,
14840 hdd_device_modetoString(pAdapter->device_mode),
14841 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014842
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014843 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014844 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014845 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014846 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014847 }
14848
14849 if (NULL == pWextState)
14850 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014851 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070014852 __func__);
14853 return -EIO;
14854 }
14855
Agarwal Ashish51325b52014-06-16 16:50:49 +053014856 if (vos_max_concurrent_connections_reached()) {
14857 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14858 return -ECONNREFUSED;
14859 }
14860
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014861 /*Try disconnecting if already in connected state*/
14862 status = wlan_hdd_try_disconnect(pAdapter);
14863 if ( 0 > status)
14864 {
14865 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14866 " IBSS connection"));
14867 return -EALREADY;
14868 }
14869
Jeff Johnson295189b2012-06-20 16:38:30 -070014870 pRoamProfile = &pWextState->roamProfile;
14871
14872 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
14873 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014874 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014875 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014876 return -EINVAL;
14877 }
14878
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070014879 /* BSSID is provided by upper layers hence no need to AUTO generate */
14880 if (NULL != params->bssid) {
14881 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
14882 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
14883 hddLog (VOS_TRACE_LEVEL_ERROR,
14884 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
14885 return -EIO;
14886 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014887 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070014888 }
krunal sonie9002db2013-11-25 14:24:17 -080014889 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
14890 {
14891 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
14892 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
14893 {
14894 hddLog (VOS_TRACE_LEVEL_ERROR,
14895 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
14896 return -EIO;
14897 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014898
14899 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080014900 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014901 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080014902 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070014903
Jeff Johnson295189b2012-06-20 16:38:30 -070014904 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070014905 if (NULL !=
14906#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
14907 params->chandef.chan)
14908#else
14909 params->channel)
14910#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014911 {
14912 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014913 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
14914 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
14915 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14916 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014917
14918 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014919 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070014920 ieee80211_frequency_to_channel(
14921#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
14922 params->chandef.chan->center_freq);
14923#else
14924 params->channel->center_freq);
14925#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014926
14927 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
14928 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070014929 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014930 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
14931 __func__);
14932 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070014933 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014934
14935 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070014936 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014937 if (channelNum == validChan[indx])
14938 {
14939 break;
14940 }
14941 }
14942 if (indx >= numChans)
14943 {
14944 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014945 __func__, channelNum);
14946 return -EINVAL;
14947 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014948 /* Set the Operational Channel */
14949 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
14950 channelNum);
14951 pRoamProfile->ChannelInfo.numOfChannels = 1;
14952 pHddStaCtx->conn_info.operationChannel = channelNum;
14953 pRoamProfile->ChannelInfo.ChannelList =
14954 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070014955 }
14956
14957 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014958 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070014959 if (status < 0)
14960 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014961 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070014962 __func__);
14963 return status;
14964 }
14965
14966 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014967 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014968 params->ssid_len, params->bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014969 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014970
14971 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014972 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014973
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014974 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014975 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014976}
14977
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014978static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
14979 struct net_device *dev,
14980 struct cfg80211_ibss_params *params
14981 )
14982{
14983 int ret = 0;
14984
14985 vos_ssr_protect(__func__);
14986 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
14987 vos_ssr_unprotect(__func__);
14988
14989 return ret;
14990}
14991
Jeff Johnson295189b2012-06-20 16:38:30 -070014992/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014993 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014994 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070014995 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014996static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014997 struct net_device *dev
14998 )
14999{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015000 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015001 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
15002 tCsrRoamProfile *pRoamProfile;
15003 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015004 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015005
15006 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015007
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015008 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15009 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
15010 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015011 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015012 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015013 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015014 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015015 }
15016
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053015017 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
15018 hdd_device_modetoString(pAdapter->device_mode),
15019 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070015020 if (NULL == pWextState)
15021 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015022 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070015023 __func__);
15024 return -EIO;
15025 }
15026
15027 pRoamProfile = &pWextState->roamProfile;
15028
15029 /* Issue disconnect only if interface type is set to IBSS */
15030 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
15031 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015032 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070015033 __func__);
15034 return -EINVAL;
15035 }
15036
15037 /* Issue Disconnect request */
15038 INIT_COMPLETION(pAdapter->disconnect_comp_var);
15039 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
15040 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
15041
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015042 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015043 return 0;
15044}
15045
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015046static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
15047 struct net_device *dev
15048 )
15049{
15050 int ret = 0;
15051
15052 vos_ssr_protect(__func__);
15053 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
15054 vos_ssr_unprotect(__func__);
15055
15056 return ret;
15057}
15058
Jeff Johnson295189b2012-06-20 16:38:30 -070015059/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015060 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070015061 * This function is used to set the phy parameters
15062 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
15063 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015064static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015065 u32 changed)
15066{
15067 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15068 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015069 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015070
15071 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015072
15073 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015074 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
15075 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015076
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015077 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015078 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015079 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015080 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015081 }
15082
Jeff Johnson295189b2012-06-20 16:38:30 -070015083 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
15084 {
15085 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
15086 WNI_CFG_RTS_THRESHOLD_STAMAX :
15087 wiphy->rts_threshold;
15088
15089 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015090 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070015091 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015092 hddLog(VOS_TRACE_LEVEL_ERROR,
15093 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015094 __func__, rts_threshold);
15095 return -EINVAL;
15096 }
15097
15098 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
15099 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015100 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015101 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015102 hddLog(VOS_TRACE_LEVEL_ERROR,
15103 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015104 __func__, rts_threshold);
15105 return -EIO;
15106 }
15107
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015108 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015109 rts_threshold);
15110 }
15111
15112 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
15113 {
15114 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
15115 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
15116 wiphy->frag_threshold;
15117
15118 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015119 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015120 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015121 hddLog(VOS_TRACE_LEVEL_ERROR,
15122 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015123 frag_threshold);
15124 return -EINVAL;
15125 }
15126
15127 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
15128 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015129 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015130 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015131 hddLog(VOS_TRACE_LEVEL_ERROR,
15132 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015133 __func__, frag_threshold);
15134 return -EIO;
15135 }
15136
15137 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
15138 frag_threshold);
15139 }
15140
15141 if ((changed & WIPHY_PARAM_RETRY_SHORT)
15142 || (changed & WIPHY_PARAM_RETRY_LONG))
15143 {
15144 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
15145 wiphy->retry_short :
15146 wiphy->retry_long;
15147
15148 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
15149 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
15150 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015151 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015152 __func__, retry_value);
15153 return -EINVAL;
15154 }
15155
15156 if (changed & WIPHY_PARAM_RETRY_SHORT)
15157 {
15158 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
15159 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015160 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015161 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015162 hddLog(VOS_TRACE_LEVEL_ERROR,
15163 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015164 __func__, retry_value);
15165 return -EIO;
15166 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015167 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015168 __func__, retry_value);
15169 }
15170 else if (changed & WIPHY_PARAM_RETRY_SHORT)
15171 {
15172 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
15173 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015174 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015175 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015176 hddLog(VOS_TRACE_LEVEL_ERROR,
15177 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015178 __func__, retry_value);
15179 return -EIO;
15180 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015181 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015182 __func__, retry_value);
15183 }
15184 }
15185
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015186 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015187 return 0;
15188}
15189
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015190static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
15191 u32 changed)
15192{
15193 int ret;
15194
15195 vos_ssr_protect(__func__);
15196 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
15197 vos_ssr_unprotect(__func__);
15198
15199 return ret;
15200}
15201
Jeff Johnson295189b2012-06-20 16:38:30 -070015202/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015203 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015204 * This function is used to set the txpower
15205 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015206static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015207#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15208 struct wireless_dev *wdev,
15209#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015210#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015211 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015212#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015213 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015214#endif
15215 int dbm)
15216{
15217 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015218 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015219 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
15220 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015221 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015222
15223 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015224
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015225 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15226 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
15227 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015228 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015229 if (0 != status)
15230 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015231 return status;
15232 }
15233
15234 hHal = pHddCtx->hHal;
15235
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015236 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
15237 dbm, ccmCfgSetCallback,
15238 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015239 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015240 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015241 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
15242 return -EIO;
15243 }
15244
15245 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
15246 dbm);
15247
15248 switch(type)
15249 {
15250 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
15251 /* Fall through */
15252 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
15253 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
15254 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015255 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
15256 __func__);
15257 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070015258 }
15259 break;
15260 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015261 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015262 __func__);
15263 return -EOPNOTSUPP;
15264 break;
15265 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015266 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
15267 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070015268 return -EIO;
15269 }
15270
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015271 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015272 return 0;
15273}
15274
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015275static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
15276#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15277 struct wireless_dev *wdev,
15278#endif
15279#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15280 enum tx_power_setting type,
15281#else
15282 enum nl80211_tx_power_setting type,
15283#endif
15284 int dbm)
15285{
15286 int ret;
15287 vos_ssr_protect(__func__);
15288 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
15289#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15290 wdev,
15291#endif
15292#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15293 type,
15294#else
15295 type,
15296#endif
15297 dbm);
15298 vos_ssr_unprotect(__func__);
15299
15300 return ret;
15301}
15302
Jeff Johnson295189b2012-06-20 16:38:30 -070015303/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015304 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015305 * This function is used to read the txpower
15306 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015307static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015308#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15309 struct wireless_dev *wdev,
15310#endif
15311 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070015312{
15313
15314 hdd_adapter_t *pAdapter;
15315 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015316 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015317
Jeff Johnsone7245742012-09-05 17:12:55 -070015318 ENTER();
15319
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015320 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015321 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015322 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015323 *dbm = 0;
15324 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015325 }
15326
Jeff Johnson295189b2012-06-20 16:38:30 -070015327 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
15328 if (NULL == pAdapter)
15329 {
15330 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
15331 return -ENOENT;
15332 }
15333
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015334 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15335 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
15336 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015337 wlan_hdd_get_classAstats(pAdapter);
15338 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
15339
Jeff Johnsone7245742012-09-05 17:12:55 -070015340 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015341 return 0;
15342}
15343
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015344static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
15345#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15346 struct wireless_dev *wdev,
15347#endif
15348 int *dbm)
15349{
15350 int ret;
15351
15352 vos_ssr_protect(__func__);
15353 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
15354#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15355 wdev,
15356#endif
15357 dbm);
15358 vos_ssr_unprotect(__func__);
15359
15360 return ret;
15361}
15362
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015363static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015364#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15365 const u8* mac,
15366#else
15367 u8* mac,
15368#endif
15369 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070015370{
15371 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15372 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15373 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053015374 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015375
15376 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
15377 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070015378
15379 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
15380 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
15381 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
15382 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
15383 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
15384 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
15385 tANI_U16 maxRate = 0;
15386 tANI_U16 myRate;
15387 tANI_U16 currentRate = 0;
15388 tANI_U8 maxSpeedMCS = 0;
15389 tANI_U8 maxMCSIdx = 0;
15390 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053015391 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070015392 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015393 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015394
Leo Chang6f8870f2013-03-26 18:11:36 -070015395#ifdef WLAN_FEATURE_11AC
15396 tANI_U32 vht_mcs_map;
15397 eDataRate11ACMaxMcs vhtMaxMcs;
15398#endif /* WLAN_FEATURE_11AC */
15399
Jeff Johnsone7245742012-09-05 17:12:55 -070015400 ENTER();
15401
Jeff Johnson295189b2012-06-20 16:38:30 -070015402 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15403 (0 == ssidlen))
15404 {
15405 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
15406 " Invalid ssidlen, %d", __func__, ssidlen);
15407 /*To keep GUI happy*/
15408 return 0;
15409 }
15410
Mukul Sharma811205f2014-07-09 21:07:30 +053015411 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
15412 {
15413 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15414 "%s: Roaming in progress, so unable to proceed this request", __func__);
15415 return 0;
15416 }
15417
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015418 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015419 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015420 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015421 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015422 }
15423
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053015424 wlan_hdd_get_station_stats(pAdapter);
15425 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015426
Kiet Lam3b17fc82013-09-27 05:24:08 +053015427 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
15428 sinfo->filled |= STATION_INFO_SIGNAL;
15429
c_hpothu09f19542014-05-30 21:53:31 +053015430 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053015431 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
15432 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053015433 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053015434 {
15435 rate_flags = pAdapter->maxRateFlags;
15436 }
c_hpothu44ff4e02014-05-08 00:13:57 +053015437
Jeff Johnson295189b2012-06-20 16:38:30 -070015438 //convert to the UI units of 100kbps
15439 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
15440
15441#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070015442 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 -070015443 sinfo->signal,
15444 pCfg->reportMaxLinkSpeed,
15445 myRate,
15446 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015447 (int) pCfg->linkSpeedRssiMid,
15448 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070015449 (int) rate_flags,
15450 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070015451#endif //LINKSPEED_DEBUG_ENABLED
15452
15453 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
15454 {
15455 // we do not want to necessarily report the current speed
15456 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
15457 {
15458 // report the max possible speed
15459 rssidx = 0;
15460 }
15461 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
15462 {
15463 // report the max possible speed with RSSI scaling
15464 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
15465 {
15466 // report the max possible speed
15467 rssidx = 0;
15468 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015469 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070015470 {
15471 // report middle speed
15472 rssidx = 1;
15473 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015474 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
15475 {
15476 // report middle speed
15477 rssidx = 2;
15478 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015479 else
15480 {
15481 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015482 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070015483 }
15484 }
15485 else
15486 {
15487 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
15488 hddLog(VOS_TRACE_LEVEL_ERROR,
15489 "%s: Invalid value for reportMaxLinkSpeed: %u",
15490 __func__, pCfg->reportMaxLinkSpeed);
15491 rssidx = 0;
15492 }
15493
15494 maxRate = 0;
15495
15496 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015497 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
15498 OperationalRates, &ORLeng))
15499 {
15500 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15501 /*To keep GUI happy*/
15502 return 0;
15503 }
15504
Jeff Johnson295189b2012-06-20 16:38:30 -070015505 for (i = 0; i < ORLeng; i++)
15506 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015507 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015508 {
15509 /* Validate Rate Set */
15510 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
15511 {
15512 currentRate = supported_data_rate[j].supported_rate[rssidx];
15513 break;
15514 }
15515 }
15516 /* Update MAX rate */
15517 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15518 }
15519
15520 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015521 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
15522 ExtendedRates, &ERLeng))
15523 {
15524 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15525 /*To keep GUI happy*/
15526 return 0;
15527 }
15528
Jeff Johnson295189b2012-06-20 16:38:30 -070015529 for (i = 0; i < ERLeng; i++)
15530 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015531 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015532 {
15533 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
15534 {
15535 currentRate = supported_data_rate[j].supported_rate[rssidx];
15536 break;
15537 }
15538 }
15539 /* Update MAX rate */
15540 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15541 }
c_hpothu79aab322014-07-14 21:11:01 +053015542
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015543 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053015544 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015545 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053015546 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070015547 {
c_hpothu79aab322014-07-14 21:11:01 +053015548 if (rate_flags & eHAL_TX_RATE_VHT80)
15549 mode = 2;
15550 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
15551 mode = 1;
15552 else
15553 mode = 0;
15554
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015555 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
15556 MCSRates, &MCSLeng))
15557 {
15558 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15559 /*To keep GUI happy*/
15560 return 0;
15561 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015562 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070015563#ifdef WLAN_FEATURE_11AC
15564 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015565 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070015566 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015567 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015568 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070015569 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070015570 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015571 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015572 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015573 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070015574 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015575 maxMCSIdx = 7;
15576 }
15577 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
15578 {
15579 maxMCSIdx = 8;
15580 }
15581 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
15582 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015583 //VHT20 is supporting 0~8
15584 if (rate_flags & eHAL_TX_RATE_VHT20)
15585 maxMCSIdx = 8;
15586 else
15587 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070015588 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015589
c_hpothu79aab322014-07-14 21:11:01 +053015590 if (0 != rssidx)/*check for scaled */
15591 {
15592 //get middle rate MCS index if rssi=1/2
15593 for (i=0; i <= maxMCSIdx; i++)
15594 {
15595 if (sinfo->signal <= rssiMcsTbl[mode][i])
15596 {
15597 maxMCSIdx = i;
15598 break;
15599 }
15600 }
15601 }
15602
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015603 if (rate_flags & eHAL_TX_RATE_VHT80)
15604 {
15605 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
15606 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
15607 }
15608 else if (rate_flags & eHAL_TX_RATE_VHT40)
15609 {
15610 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
15611 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
15612 }
15613 else if (rate_flags & eHAL_TX_RATE_VHT20)
15614 {
15615 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
15616 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
15617 }
15618
Leo Chang6f8870f2013-03-26 18:11:36 -070015619 maxSpeedMCS = 1;
15620 if (currentRate > maxRate)
15621 {
15622 maxRate = currentRate;
15623 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015624
Leo Chang6f8870f2013-03-26 18:11:36 -070015625 }
15626 else
15627#endif /* WLAN_FEATURE_11AC */
15628 {
15629 if (rate_flags & eHAL_TX_RATE_HT40)
15630 {
15631 rateFlag |= 1;
15632 }
15633 if (rate_flags & eHAL_TX_RATE_SGI)
15634 {
15635 rateFlag |= 2;
15636 }
15637
Girish Gowli01abcee2014-07-31 20:18:55 +053015638 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053015639 if (rssidx == 1 || rssidx == 2)
15640 {
15641 //get middle rate MCS index if rssi=1/2
15642 for (i=0; i <= 7; i++)
15643 {
15644 if (sinfo->signal <= rssiMcsTbl[mode][i])
15645 {
15646 temp = i+1;
15647 break;
15648 }
15649 }
15650 }
c_hpothu79aab322014-07-14 21:11:01 +053015651
15652 for (i = 0; i < MCSLeng; i++)
15653 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015654 for (j = 0; j < temp; j++)
15655 {
15656 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
15657 {
15658 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053015659 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070015660 break;
15661 }
15662 }
15663 if ((j < temp) && (currentRate > maxRate))
15664 {
15665 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070015666 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015667 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053015668 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015669 }
15670 }
15671
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015672 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
15673 {
15674 maxRate = myRate;
15675 maxSpeedMCS = 1;
15676 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
15677 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015678 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053015679 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070015680 {
15681 maxRate = myRate;
15682 if (rate_flags & eHAL_TX_RATE_LEGACY)
15683 {
15684 maxSpeedMCS = 0;
15685 }
15686 else
15687 {
15688 maxSpeedMCS = 1;
15689 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
15690 }
15691 }
15692
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015693 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070015694 {
15695 sinfo->txrate.legacy = maxRate;
15696#ifdef LINKSPEED_DEBUG_ENABLED
15697 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
15698#endif //LINKSPEED_DEBUG_ENABLED
15699 }
15700 else
15701 {
15702 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070015703#ifdef WLAN_FEATURE_11AC
15704 sinfo->txrate.nss = 1;
15705 if (rate_flags & eHAL_TX_RATE_VHT80)
15706 {
15707 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015708 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070015709 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015710 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070015711 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015712 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15713 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15714 }
15715 else if (rate_flags & eHAL_TX_RATE_VHT20)
15716 {
15717 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15718 }
15719#endif /* WLAN_FEATURE_11AC */
15720 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
15721 {
15722 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
15723 if (rate_flags & eHAL_TX_RATE_HT40)
15724 {
15725 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15726 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015727 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015728 if (rate_flags & eHAL_TX_RATE_SGI)
15729 {
15730 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
15731 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015732
Jeff Johnson295189b2012-06-20 16:38:30 -070015733#ifdef LINKSPEED_DEBUG_ENABLED
15734 pr_info("Reporting MCS rate %d flags %x\n",
15735 sinfo->txrate.mcs,
15736 sinfo->txrate.flags );
15737#endif //LINKSPEED_DEBUG_ENABLED
15738 }
15739 }
15740 else
15741 {
15742 // report current rate instead of max rate
15743
15744 if (rate_flags & eHAL_TX_RATE_LEGACY)
15745 {
15746 //provide to the UI in units of 100kbps
15747 sinfo->txrate.legacy = myRate;
15748#ifdef LINKSPEED_DEBUG_ENABLED
15749 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
15750#endif //LINKSPEED_DEBUG_ENABLED
15751 }
15752 else
15753 {
15754 //must be MCS
15755 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070015756#ifdef WLAN_FEATURE_11AC
15757 sinfo->txrate.nss = 1;
15758 if (rate_flags & eHAL_TX_RATE_VHT80)
15759 {
15760 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15761 }
15762 else
15763#endif /* WLAN_FEATURE_11AC */
15764 {
15765 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
15766 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015767 if (rate_flags & eHAL_TX_RATE_SGI)
15768 {
15769 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
15770 }
15771 if (rate_flags & eHAL_TX_RATE_HT40)
15772 {
15773 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15774 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015775#ifdef WLAN_FEATURE_11AC
15776 else if (rate_flags & eHAL_TX_RATE_VHT80)
15777 {
15778 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
15779 }
15780#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070015781#ifdef LINKSPEED_DEBUG_ENABLED
15782 pr_info("Reporting actual MCS rate %d flags %x\n",
15783 sinfo->txrate.mcs,
15784 sinfo->txrate.flags );
15785#endif //LINKSPEED_DEBUG_ENABLED
15786 }
15787 }
15788 sinfo->filled |= STATION_INFO_TX_BITRATE;
15789
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070015790 sinfo->tx_packets =
15791 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
15792 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
15793 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
15794 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
15795
15796 sinfo->tx_retries =
15797 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
15798 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
15799 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
15800 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
15801
15802 sinfo->tx_failed =
15803 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
15804 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
15805 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
15806 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
15807
15808 sinfo->filled |=
15809 STATION_INFO_TX_PACKETS |
15810 STATION_INFO_TX_RETRIES |
15811 STATION_INFO_TX_FAILED;
15812
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015813 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15814 TRACE_CODE_HDD_CFG80211_GET_STA,
15815 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070015816 EXIT();
15817 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015818}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015819#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15820static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
15821 const u8* mac, struct station_info *sinfo)
15822#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015823static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
15824 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015825#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015826{
15827 int ret;
15828
15829 vos_ssr_protect(__func__);
15830 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
15831 vos_ssr_unprotect(__func__);
15832
15833 return ret;
15834}
15835
15836static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070015837 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070015838{
15839 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015840 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015841 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015842 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015843
Jeff Johnsone7245742012-09-05 17:12:55 -070015844 ENTER();
15845
Jeff Johnson295189b2012-06-20 16:38:30 -070015846 if (NULL == pAdapter)
15847 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015848 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015849 return -ENODEV;
15850 }
15851
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015852 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15853 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
15854 pAdapter->sessionId, timeout));
15855
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015856 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015857 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015858 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015859 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015860 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015861 }
15862
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015863 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
15864 (TRUE == pHddCtx->hdd_wlan_suspended) &&
15865 (pHddCtx->cfg_ini->fhostArpOffload) &&
15866 (eConnectionState_Associated ==
15867 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
15868 {
Amar Singhald53568e2013-09-26 11:03:45 -070015869
15870 hddLog(VOS_TRACE_LEVEL_INFO,
15871 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053015872 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015873 if (!VOS_IS_STATUS_SUCCESS(vos_status))
15874 {
15875 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015876 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015877 __func__, vos_status);
15878 }
15879 }
15880
Jeff Johnson295189b2012-06-20 16:38:30 -070015881 /**The get power cmd from the supplicant gets updated by the nl only
15882 *on successful execution of the function call
15883 *we are oppositely mapped w.r.t mode in the driver
15884 **/
15885 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
15886
15887 if (VOS_STATUS_E_FAILURE == vos_status)
15888 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015889 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15890 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015891 return -EINVAL;
15892 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015893 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015894 return 0;
15895}
15896
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015897static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
15898 struct net_device *dev, bool mode, int timeout)
15899{
15900 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070015901
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015902 vos_ssr_protect(__func__);
15903 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
15904 vos_ssr_unprotect(__func__);
15905
15906 return ret;
15907}
Sushant Kaushik084f6592015-09-10 13:11:56 +053015908
Jeff Johnson295189b2012-06-20 16:38:30 -070015909#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015910static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
15911 struct net_device *netdev,
15912 u8 key_index)
15913{
15914 ENTER();
15915 return 0;
15916}
15917
Jeff Johnson295189b2012-06-20 16:38:30 -070015918static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015919 struct net_device *netdev,
15920 u8 key_index)
15921{
15922 int ret;
15923 vos_ssr_protect(__func__);
15924 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
15925 vos_ssr_unprotect(__func__);
15926 return ret;
15927}
15928#endif //LINUX_VERSION_CODE
15929
15930#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
15931static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
15932 struct net_device *dev,
15933 struct ieee80211_txq_params *params)
15934{
15935 ENTER();
15936 return 0;
15937}
15938#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
15939static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
15940 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070015941{
Jeff Johnsone7245742012-09-05 17:12:55 -070015942 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070015943 return 0;
15944}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015945#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070015946
15947#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
15948static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015949 struct net_device *dev,
15950 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070015951{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015952 int ret;
15953
15954 vos_ssr_protect(__func__);
15955 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
15956 vos_ssr_unprotect(__func__);
15957 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070015958}
15959#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
15960static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
15961 struct ieee80211_txq_params *params)
15962{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015963 int ret;
15964
15965 vos_ssr_protect(__func__);
15966 ret = __wlan_hdd_set_txq_params(wiphy, params);
15967 vos_ssr_unprotect(__func__);
15968 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070015969}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015970#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015971
Naresh Jayaram69e3f282014-10-14 12:29:12 +053015972static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015973 struct net_device *dev,
15974 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070015975{
15976 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015977 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015978 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015979 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015980 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015981 v_CONTEXT_t pVosContext = NULL;
15982 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015983
Jeff Johnsone7245742012-09-05 17:12:55 -070015984 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015985
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015986 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070015987 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015988 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015989 return -EINVAL;
15990 }
15991
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015992 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15993 TRACE_CODE_HDD_CFG80211_DEL_STA,
15994 pAdapter->sessionId, pAdapter->device_mode));
15995
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015996 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15997 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015998 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015999 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016000 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016001 }
16002
Jeff Johnson295189b2012-06-20 16:38:30 -070016003 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016004 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070016005 )
16006 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016007 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
16008 pSapCtx = VOS_GET_SAP_CB(pVosContext);
16009 if(pSapCtx == NULL){
16010 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16011 FL("psapCtx is NULL"));
16012 return -ENOENT;
16013 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016014 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070016015 {
16016 v_U16_t i;
16017 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
16018 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016019 if ((pSapCtx->aStaInfo[i].isUsed) &&
16020 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070016021 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016022 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016023 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016024 ETHER_ADDR_LEN);
16025
Jeff Johnson295189b2012-06-20 16:38:30 -070016026 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016027 "%s: Delete STA with MAC::"
16028 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016029 __func__,
16030 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
16031 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070016032 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016033 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070016034 }
16035 }
16036 }
16037 else
16038 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016039
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016040 vos_status = hdd_softap_GetStaId(pAdapter,
16041 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016042 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16043 {
16044 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016045 "%s: Skip this DEL STA as this is not used::"
16046 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016047 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016048 return -ENOENT;
16049 }
16050
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016051 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016052 {
16053 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016054 "%s: Skip this DEL STA as deauth is in progress::"
16055 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016056 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016057 return -ENOENT;
16058 }
16059
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016060 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016061
Jeff Johnson295189b2012-06-20 16:38:30 -070016062 hddLog(VOS_TRACE_LEVEL_INFO,
16063 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016064 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016065 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016066 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016067
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016068 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016069 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16070 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016071 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016072 hddLog(VOS_TRACE_LEVEL_INFO,
16073 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016074 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016075 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016076 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016077 return -ENOENT;
16078 }
16079
Jeff Johnson295189b2012-06-20 16:38:30 -070016080 }
16081 }
16082
16083 EXIT();
16084
16085 return 0;
16086}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016087
16088#ifdef CFG80211_DEL_STA_V2
16089static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16090 struct net_device *dev,
16091 struct station_del_parameters *param)
16092#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016093#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16094static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16095 struct net_device *dev, const u8 *mac)
16096#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016097static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16098 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016099#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016100#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016101{
16102 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016103 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070016104
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016105 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016106
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016107#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016108 if (NULL == param) {
16109 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016110 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016111 return -EINVAL;
16112 }
16113
16114 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
16115 param->subtype, &delStaParams);
16116
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016117#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053016118 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016119 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016120#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016121 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
16122
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016123 vos_ssr_unprotect(__func__);
16124
16125 return ret;
16126}
16127
16128static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016129 struct net_device *dev,
16130#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16131 const u8 *mac,
16132#else
16133 u8 *mac,
16134#endif
16135 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016136{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016137 hdd_adapter_t *pAdapter;
16138 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016139 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016140#ifdef FEATURE_WLAN_TDLS
16141 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016142
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016143 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016144
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016145 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16146 if (NULL == pAdapter)
16147 {
16148 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16149 "%s: Adapter is NULL",__func__);
16150 return -EINVAL;
16151 }
16152 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16153 status = wlan_hdd_validate_context(pHddCtx);
16154 if (0 != status)
16155 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016156 return status;
16157 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016158
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016159 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16160 TRACE_CODE_HDD_CFG80211_ADD_STA,
16161 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016162 mask = params->sta_flags_mask;
16163
16164 set = params->sta_flags_set;
16165
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016166 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016167 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
16168 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016169
16170 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
16171 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080016172 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016173 }
16174 }
16175#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016176 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016177 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016178}
16179
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016180#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16181static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16182 struct net_device *dev, const u8 *mac,
16183 struct station_parameters *params)
16184#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016185static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16186 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016187#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016188{
16189 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016190
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016191 vos_ssr_protect(__func__);
16192 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
16193 vos_ssr_unprotect(__func__);
16194
16195 return ret;
16196}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016197#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070016198
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016199static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070016200 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016201{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016202 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16203 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016204 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016205 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016206 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016207 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070016208
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016209 ENTER();
16210
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016211 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016212 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016213 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016214 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016215 return -EINVAL;
16216 }
16217
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016218 if (!pmksa) {
16219 hddLog(LOGE, FL("pmksa is NULL"));
16220 return -EINVAL;
16221 }
16222
16223 if (!pmksa->bssid || !pmksa->pmkid) {
16224 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
16225 pmksa->bssid, pmksa->pmkid);
16226 return -EINVAL;
16227 }
16228
16229 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
16230 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16231
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016232 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16233 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016234 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016235 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016236 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016237 }
16238
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016239 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016240 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16241
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016242 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
16243 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016244
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016245 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016246 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016247 &pmk_id, 1, FALSE);
16248
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016249 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16250 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
16251 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016252
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016253 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016254 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016255}
16256
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016257static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
16258 struct cfg80211_pmksa *pmksa)
16259{
16260 int ret;
16261
16262 vos_ssr_protect(__func__);
16263 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
16264 vos_ssr_unprotect(__func__);
16265
16266 return ret;
16267}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016268
Wilson Yang6507c4e2013-10-01 20:11:19 -070016269
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016270static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070016271 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016272{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016273 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16274 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016275 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016276 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016277
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016278 ENTER();
16279
Wilson Yang6507c4e2013-10-01 20:11:19 -070016280 /* Validate pAdapter */
16281 if (NULL == pAdapter)
16282 {
16283 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
16284 return -EINVAL;
16285 }
16286
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016287 if (!pmksa) {
16288 hddLog(LOGE, FL("pmksa is NULL"));
16289 return -EINVAL;
16290 }
16291
16292 if (!pmksa->bssid) {
16293 hddLog(LOGE, FL("pmksa->bssid is NULL"));
16294 return -EINVAL;
16295 }
16296
Kiet Lam98c46a12014-10-31 15:34:57 -070016297 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
16298 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16299
Wilson Yang6507c4e2013-10-01 20:11:19 -070016300 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16301 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016302 if (0 != status)
16303 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016304 return status;
16305 }
16306
16307 /*Retrieve halHandle*/
16308 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16309
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016310 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16311 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
16312 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016313 /* Delete the PMKID CSR cache */
16314 if (eHAL_STATUS_SUCCESS !=
16315 sme_RoamDelPMKIDfromCache(halHandle,
16316 pAdapter->sessionId, pmksa->bssid, FALSE)) {
16317 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
16318 MAC_ADDR_ARRAY(pmksa->bssid));
16319 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016320 }
16321
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016322 EXIT();
16323 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016324}
16325
Wilson Yang6507c4e2013-10-01 20:11:19 -070016326
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016327static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
16328 struct cfg80211_pmksa *pmksa)
16329{
16330 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016331
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016332 vos_ssr_protect(__func__);
16333 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
16334 vos_ssr_unprotect(__func__);
16335
16336 return ret;
16337
16338}
16339
16340static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016341{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016342 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16343 tHalHandle halHandle;
16344 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016345 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016346
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016347 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070016348
16349 /* Validate pAdapter */
16350 if (NULL == pAdapter)
16351 {
16352 hddLog(VOS_TRACE_LEVEL_ERROR,
16353 "%s: Invalid Adapter" ,__func__);
16354 return -EINVAL;
16355 }
16356
16357 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16358 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016359 if (0 != status)
16360 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016361 return status;
16362 }
16363
16364 /*Retrieve halHandle*/
16365 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16366
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016367 /* Flush the PMKID cache in CSR */
16368 if (eHAL_STATUS_SUCCESS !=
16369 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
16370 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
16371 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016372 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016373 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080016374 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016375}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016376
16377static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
16378{
16379 int ret;
16380
16381 vos_ssr_protect(__func__);
16382 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
16383 vos_ssr_unprotect(__func__);
16384
16385 return ret;
16386}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016387#endif
16388
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016389#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016390static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16391 struct net_device *dev,
16392 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016393{
16394 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16395 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016396 hdd_context_t *pHddCtx;
16397 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016398
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016399 ENTER();
16400
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016401 if (NULL == pAdapter)
16402 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016403 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016404 return -ENODEV;
16405 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016406 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16407 ret = wlan_hdd_validate_context(pHddCtx);
16408 if (0 != ret)
16409 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016410 return ret;
16411 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016412 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016413 if (NULL == pHddStaCtx)
16414 {
16415 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
16416 return -EINVAL;
16417 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016418
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016419 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16420 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
16421 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016422 // Added for debug on reception of Re-assoc Req.
16423 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
16424 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016425 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016426 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080016427 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016428 }
16429
16430#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080016431 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016432 ftie->ie_len);
16433#endif
16434
16435 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016436 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
16437 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016438 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016439
16440 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016441 return 0;
16442}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016443
16444static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16445 struct net_device *dev,
16446 struct cfg80211_update_ft_ies_params *ftie)
16447{
16448 int ret;
16449
16450 vos_ssr_protect(__func__);
16451 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
16452 vos_ssr_unprotect(__func__);
16453
16454 return ret;
16455}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016456#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016457
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016458#ifdef FEATURE_WLAN_SCAN_PNO
16459
16460void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
16461 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
16462{
16463 int ret;
16464 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
16465 hdd_context_t *pHddCtx;
16466
Nirav Shah80830bf2013-12-31 16:35:12 +053016467 ENTER();
16468
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016469 if (NULL == pAdapter)
16470 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016471 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016472 "%s: HDD adapter is Null", __func__);
16473 return ;
16474 }
16475
16476 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16477 if (NULL == pHddCtx)
16478 {
16479 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16480 "%s: HDD context is Null!!!", __func__);
16481 return ;
16482 }
16483
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016484 spin_lock(&pHddCtx->schedScan_lock);
16485 if (TRUE == pHddCtx->isWiphySuspended)
16486 {
16487 pHddCtx->isSchedScanUpdatePending = TRUE;
16488 spin_unlock(&pHddCtx->schedScan_lock);
16489 hddLog(VOS_TRACE_LEVEL_INFO,
16490 "%s: Update cfg80211 scan database after it resume", __func__);
16491 return ;
16492 }
16493 spin_unlock(&pHddCtx->schedScan_lock);
16494
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016495 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
16496
16497 if (0 > ret)
16498 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053016499 else
16500 {
16501 /* Acquire wakelock to handle the case where APP's tries to suspend
16502 * immediatly after the driver gets connect request(i.e after pno)
16503 * from supplicant, this result in app's is suspending and not able
16504 * to process the connect request to AP */
16505 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
16506 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016507 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016508 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16509 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016510}
16511
16512/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016513 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016514 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016515 */
16516static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
16517{
16518 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
16519 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016520 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016521 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16522 int status = 0;
16523 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
16524
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016525 /* The current firmware design does not allow PNO during any
16526 * active sessions. Hence, determine the active sessions
16527 * and return a failure.
16528 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016529 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
16530 {
16531 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016532 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016533
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016534 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
16535 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
16536 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
16537 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
16538 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053016539 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016540 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016541 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016542 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016543 }
16544 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16545 pAdapterNode = pNext;
16546 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016547 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016548}
16549
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016550void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
16551{
16552 hdd_adapter_t *pAdapter = callbackContext;
16553 hdd_context_t *pHddCtx;
16554
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016555 ENTER();
16556
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016557 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
16558 {
16559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16560 FL("Invalid adapter or adapter has invalid magic"));
16561 return;
16562 }
16563
16564 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16565 if (0 != wlan_hdd_validate_context(pHddCtx))
16566 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016567 return;
16568 }
16569
c_hpothub53c45d2014-08-18 16:53:14 +053016570 if (VOS_STATUS_SUCCESS != status)
16571 {
16572 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016573 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053016574 pHddCtx->isPnoEnable = FALSE;
16575 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016576
16577 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
16578 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016579 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016580}
16581
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016582/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016583 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
16584 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016585 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016586static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016587 struct net_device *dev, struct cfg80211_sched_scan_request *request)
16588{
16589 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016590 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016591 hdd_context_t *pHddCtx;
16592 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016593 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053016594 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
16595 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016596 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16597 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016598 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016599 hdd_config_t *pConfig = NULL;
16600 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016601
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016602 ENTER();
16603
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016604 if (NULL == pAdapter)
16605 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016607 "%s: HDD adapter is Null", __func__);
16608 return -ENODEV;
16609 }
16610
16611 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016612 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016613
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016614 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016615 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016616 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016617 }
16618
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016619 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016620 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16621 if (NULL == hHal)
16622 {
16623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16624 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016625 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016626 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016627 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16628 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
16629 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053016630 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016631 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053016632 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016633 {
16634 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16635 "%s: aborting the existing scan is unsuccessfull", __func__);
16636 return -EBUSY;
16637 }
16638
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016639 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016640 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016641 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016642 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016643 return -EBUSY;
16644 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016645
c_hpothu37f21312014-04-09 21:49:54 +053016646 if (TRUE == pHddCtx->isPnoEnable)
16647 {
16648 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
16649 FL("already PNO is enabled"));
16650 return -EBUSY;
16651 }
c_hpothu225aa7c2014-10-22 17:45:13 +053016652
16653 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
16654 {
16655 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16656 "%s: abort ROC failed ", __func__);
16657 return -EBUSY;
16658 }
16659
c_hpothu37f21312014-04-09 21:49:54 +053016660 pHddCtx->isPnoEnable = TRUE;
16661
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016662 pnoRequest.enable = 1; /*Enable PNO */
16663 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016664
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016665 if (( !pnoRequest.ucNetworksCount ) ||
16666 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016667 {
16668 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016669 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016670 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016671 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016672 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016673 goto error;
16674 }
16675
16676 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
16677 {
16678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016679 "%s: Incorrect number of channels %d",
16680 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016681 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016682 goto error;
16683 }
16684
16685 /* Framework provides one set of channels(all)
16686 * common for all saved profile */
16687 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16688 channels_allowed, &num_channels_allowed))
16689 {
16690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16691 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016692 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016693 goto error;
16694 }
16695 /* Checking each channel against allowed channel list */
16696 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053016697 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016698 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016699 char chList [(request->n_channels*5)+1];
16700 int len;
16701 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016702 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016703 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016704 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016705 if (request->channels[i]->hw_value == channels_allowed[indx])
16706 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016707 if ((!pConfig->enableDFSPnoChnlScan) &&
16708 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
16709 {
16710 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16711 "%s : Dropping DFS channel : %d",
16712 __func__,channels_allowed[indx]);
16713 num_ignore_dfs_ch++;
16714 break;
16715 }
16716
Nirav Shah80830bf2013-12-31 16:35:12 +053016717 valid_ch[num_ch++] = request->channels[i]->hw_value;
16718 len += snprintf(chList+len, 5, "%d ",
16719 request->channels[i]->hw_value);
16720 break ;
16721 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016722 }
16723 }
Nirav Shah80830bf2013-12-31 16:35:12 +053016724 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016725
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016726 /*If all channels are DFS and dropped, then ignore the PNO request*/
16727 if (num_ignore_dfs_ch == request->n_channels)
16728 {
16729 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16730 "%s : All requested channels are DFS channels", __func__);
16731 ret = -EINVAL;
16732 goto error;
16733 }
16734 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016735
16736 pnoRequest.aNetworks =
16737 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16738 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016739 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016740 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16741 FL("failed to allocate memory aNetworks %u"),
16742 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16743 goto error;
16744 }
16745 vos_mem_zero(pnoRequest.aNetworks,
16746 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16747
16748 /* Filling per profile params */
16749 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
16750 {
16751 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016752 request->match_sets[i].ssid.ssid_len;
16753
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016754 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
16755 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016756 {
16757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016758 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016759 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016760 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016761 goto error;
16762 }
16763
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016764 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016765 request->match_sets[i].ssid.ssid,
16766 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016767 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16768 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016769 i, pnoRequest.aNetworks[i].ssId.ssId);
16770 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
16771 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
16772 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016773
16774 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016775 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
16776 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016777
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016778 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016779 }
16780
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016781 for (i = 0; i < request->n_ssids; i++)
16782 {
16783 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016784 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016785 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016786 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016787 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016788 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016789 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016790 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016791 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016792 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016793 break;
16794 }
16795 j++;
16796 }
16797 }
16798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16799 "Number of hidden networks being Configured = %d",
16800 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080016802 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016803
16804 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
16805 if (pnoRequest.p24GProbeTemplate == NULL)
16806 {
16807 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16808 FL("failed to allocate memory p24GProbeTemplate %u"),
16809 SIR_PNO_MAX_PB_REQ_SIZE);
16810 goto error;
16811 }
16812
16813 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
16814 if (pnoRequest.p5GProbeTemplate == NULL)
16815 {
16816 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16817 FL("failed to allocate memory p5GProbeTemplate %u"),
16818 SIR_PNO_MAX_PB_REQ_SIZE);
16819 goto error;
16820 }
16821
16822 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
16823 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
16824
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053016825 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
16826 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016827 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016828 pnoRequest.us24GProbeTemplateLen = request->ie_len;
16829 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
16830 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016831
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016832 pnoRequest.us5GProbeTemplateLen = request->ie_len;
16833 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
16834 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016835 }
16836
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016837 /* Driver gets only one time interval which is hardcoded in
16838 * supplicant for 10000ms. Taking power consumption into account 6 timers
16839 * will be used, Timervalue is increased exponentially i.e 10,20,40,
16840 * 80,160,320 secs. And number of scan cycle for each timer
16841 * is configurable through INI param gPNOScanTimerRepeatValue.
16842 * If it is set to 0 only one timer will be used and PNO scan cycle
16843 * will be repeated after each interval specified by supplicant
16844 * till PNO is disabled.
16845 */
16846 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016847 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016848 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016849 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016850 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
16851
16852 tempInterval = (request->interval)/1000;
16853 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16854 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
16855 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016856 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016857 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016858 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016859 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016860 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016861 tempInterval *= 2;
16862 }
16863 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016864 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016865
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016866 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016867
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016868 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016869 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
16870 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016871 pAdapter->pno_req_status = 0;
16872
Nirav Shah80830bf2013-12-31 16:35:12 +053016873 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16874 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016875 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
16876 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053016877
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016878 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016879 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016880 hdd_cfg80211_sched_scan_done_callback, pAdapter);
16881 if (eHAL_STATUS_SUCCESS != status)
16882 {
16883 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016884 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016885 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016886 goto error;
16887 }
16888
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016889 ret = wait_for_completion_timeout(
16890 &pAdapter->pno_comp_var,
16891 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
16892 if (0 >= ret)
16893 {
16894 // Did not receive the response for PNO enable in time.
16895 // Assuming the PNO enable was success.
16896 // Returning error from here, because we timeout, results
16897 // in side effect of Wifi (Wifi Setting) not to work.
16898 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16899 FL("Timed out waiting for PNO to be Enabled"));
16900 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016901 }
16902
16903 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053016904 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016905
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016906error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016907 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16908 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053016909 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016910 if (pnoRequest.aNetworks)
16911 vos_mem_free(pnoRequest.aNetworks);
16912 if (pnoRequest.p24GProbeTemplate)
16913 vos_mem_free(pnoRequest.p24GProbeTemplate);
16914 if (pnoRequest.p5GProbeTemplate)
16915 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016916
16917 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016918 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016919}
16920
16921/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016922 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
16923 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016924 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016925static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
16926 struct net_device *dev, struct cfg80211_sched_scan_request *request)
16927{
16928 int ret;
16929
16930 vos_ssr_protect(__func__);
16931 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
16932 vos_ssr_unprotect(__func__);
16933
16934 return ret;
16935}
16936
16937/*
16938 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
16939 * Function to disable PNO
16940 */
16941static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016942 struct net_device *dev)
16943{
16944 eHalStatus status = eHAL_STATUS_FAILURE;
16945 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16946 hdd_context_t *pHddCtx;
16947 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016948 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016949 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016950
16951 ENTER();
16952
16953 if (NULL == pAdapter)
16954 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016955 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016956 "%s: HDD adapter is Null", __func__);
16957 return -ENODEV;
16958 }
16959
16960 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016961
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016962 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016963 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016964 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016965 "%s: HDD context is Null", __func__);
16966 return -ENODEV;
16967 }
16968
16969 /* The return 0 is intentional when isLogpInProgress and
16970 * isLoadUnloadInProgress. We did observe a crash due to a return of
16971 * failure in sched_scan_stop , especially for a case where the unload
16972 * of the happens at the same time. The function __cfg80211_stop_sched_scan
16973 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
16974 * success. If it returns a failure , then its next invocation due to the
16975 * clean up of the second interface will have the dev pointer corresponding
16976 * to the first one leading to a crash.
16977 */
16978 if (pHddCtx->isLogpInProgress)
16979 {
16980 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16981 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053016982 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016983 return ret;
16984 }
16985
Mihir Shete18156292014-03-11 15:38:30 +053016986 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016987 {
16988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16989 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
16990 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016991 }
16992
16993 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16994 if (NULL == hHal)
16995 {
16996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16997 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016998 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016999 }
17000
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017001 pnoRequest.enable = 0; /* Disable PNO */
17002 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017003
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017004 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17005 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
17006 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053017007 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017008 pAdapter->sessionId,
17009 NULL, pAdapter);
17010 if (eHAL_STATUS_SUCCESS != status)
17011 {
17012 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17013 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017014 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017015 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017016 }
c_hpothu37f21312014-04-09 21:49:54 +053017017 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017018
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017019error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017020 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053017021 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017022
17023 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053017024 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017025}
17026
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053017027/*
17028 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
17029 * NL interface to disable PNO
17030 */
17031static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
17032 struct net_device *dev)
17033{
17034 int ret;
17035
17036 vos_ssr_protect(__func__);
17037 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
17038 vos_ssr_unprotect(__func__);
17039
17040 return ret;
17041}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017042#endif /*FEATURE_WLAN_SCAN_PNO*/
17043
17044
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017045#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017046#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017047static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17048 struct net_device *dev,
17049 u8 *peer, u8 action_code,
17050 u8 dialog_token,
17051 u16 status_code, u32 peer_capability,
17052 const u8 *buf, size_t len)
17053#else /* TDLS_MGMT_VERSION2 */
17054#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17055static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17056 struct net_device *dev,
17057 const u8 *peer, u8 action_code,
17058 u8 dialog_token, u16 status_code,
17059 u32 peer_capability, bool initiator,
17060 const u8 *buf, size_t len)
17061#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17062static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17063 struct net_device *dev,
17064 const u8 *peer, u8 action_code,
17065 u8 dialog_token, u16 status_code,
17066 u32 peer_capability, const u8 *buf,
17067 size_t len)
17068#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17069static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17070 struct net_device *dev,
17071 u8 *peer, u8 action_code,
17072 u8 dialog_token,
17073 u16 status_code, u32 peer_capability,
17074 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017075#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017076static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17077 struct net_device *dev,
17078 u8 *peer, u8 action_code,
17079 u8 dialog_token,
17080 u16 status_code, const u8 *buf,
17081 size_t len)
17082#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017083#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017084{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017085 hdd_adapter_t *pAdapter;
17086 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017087 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070017088 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080017089 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070017090 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017091 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017092 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017093#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017094 u32 peer_capability = 0;
17095#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017096 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017097 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017098
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017099 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17100 if (NULL == pAdapter)
17101 {
17102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17103 "%s: Adapter is NULL",__func__);
17104 return -EINVAL;
17105 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017106 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17107 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
17108 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017109
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017110 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017111 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017112 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017114 "Invalid arguments");
17115 return -EINVAL;
17116 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017117
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017118 if (pHddCtx->isLogpInProgress)
17119 {
17120 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17121 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053017122 wlan_hdd_tdls_set_link_status(pAdapter,
17123 peer,
17124 eTDLS_LINK_IDLE,
17125 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017126 return -EBUSY;
17127 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017128
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017129 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
17130 {
17131 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17132 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17133 return -EAGAIN;
17134 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017135
Hoonki Lee27511902013-03-14 18:19:06 -070017136 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017137 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017139 "%s: TDLS mode is disabled OR not enabled in FW."
17140 MAC_ADDRESS_STR " action %d declined.",
17141 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017142 return -ENOTSUPP;
17143 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017144
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017145 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17146
17147 if( NULL == pHddStaCtx )
17148 {
17149 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17150 "%s: HDD station context NULL ",__func__);
17151 return -EINVAL;
17152 }
17153
17154 /* STA should be connected and authenticated
17155 * before sending any TDLS frames
17156 */
17157 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17158 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
17159 {
17160 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17161 "STA is not connected or unauthenticated. "
17162 "connState %u, uIsAuthenticated %u",
17163 pHddStaCtx->conn_info.connState,
17164 pHddStaCtx->conn_info.uIsAuthenticated);
17165 return -EAGAIN;
17166 }
17167
Hoonki Lee27511902013-03-14 18:19:06 -070017168 /* other than teardown frame, other mgmt frames are not sent if disabled */
17169 if (SIR_MAC_TDLS_TEARDOWN != action_code)
17170 {
17171 /* if tdls_mode is disabled to respond to peer's request */
17172 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
17173 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017174 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017175 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017176 " TDLS mode is disabled. action %d declined.",
17177 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070017178
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017179 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070017180 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053017181
17182 if (vos_max_concurrent_connections_reached())
17183 {
17184 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17185 return -EINVAL;
17186 }
Hoonki Lee27511902013-03-14 18:19:06 -070017187 }
17188
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017189 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
17190 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053017191 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017192 {
17193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017194 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017195 " TDLS setup is ongoing. action %d declined.",
17196 __func__, MAC_ADDR_ARRAY(peer), action_code);
17197 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017198 }
17199 }
17200
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017201 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
17202 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080017203 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017204 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17205 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017206 {
17207 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
17208 we return error code at 'add_station()'. Hence we have this
17209 check again in addtion to add_station().
17210 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017211 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017212 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017213 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17214 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017215 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
17216 __func__, MAC_ADDR_ARRAY(peer), action_code,
17217 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053017218 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080017219 }
17220 else
17221 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017222 /* maximum reached. tweak to send error code to peer and return
17223 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017224 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017225 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17226 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017227 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
17228 __func__, MAC_ADDR_ARRAY(peer), status_code,
17229 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070017230 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017231 /* fall through to send setup resp with failure status
17232 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017233 }
17234 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017235 else
17236 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017237 mutex_lock(&pHddCtx->tdls_lock);
17238 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017239 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017240 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017241 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017243 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
17244 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017245 return -EPERM;
17246 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017247 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017248 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017249 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017250
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017251 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017252 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017253 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
17254 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017255
Hoonki Leea34dd892013-02-05 22:56:02 -080017256 /*Except teardown responder will not be used so just make 0*/
17257 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017258 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080017259 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017260
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017261 mutex_lock(&pHddCtx->tdls_lock);
17262 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017263
17264 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
17265 responder = pTdlsPeer->is_responder;
17266 else
Hoonki Leea34dd892013-02-05 22:56:02 -080017267 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017268 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017269 "%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 -070017270 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
17271 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017272 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017273 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080017274 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017275 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017276 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017277
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017278 /* Discard TDLS setup if peer is removed by user app */
17279 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
17280 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17281 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
17282 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
17283
17284 mutex_lock(&pHddCtx->tdls_lock);
17285 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
17286 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
17287 mutex_unlock(&pHddCtx->tdls_lock);
17288 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
17289 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
17290 MAC_ADDR_ARRAY(peer), action_code);
17291 return -EINVAL;
17292 }
17293 mutex_unlock(&pHddCtx->tdls_lock);
17294 }
17295
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017296 /* For explicit trigger of DIS_REQ come out of BMPS for
17297 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070017298 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017299 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
17300 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070017301 {
17302 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
17303 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017305 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017306 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
17307 if (status != VOS_STATUS_SUCCESS) {
17308 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
17309 }
Hoonki Lee14621352013-04-16 17:51:19 -070017310 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017311 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017312 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017313 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
17314 }
17315 }
Hoonki Lee14621352013-04-16 17:51:19 -070017316 }
17317
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017318 /* make sure doesn't call send_mgmt() while it is pending */
17319 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
17320 {
17321 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017322 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017323 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017324 ret = -EBUSY;
17325 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017326 }
17327
17328 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017329 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
17330
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017331 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
17332 pAdapter->sessionId, peer, action_code, dialog_token,
17333 status_code, peer_capability, (tANI_U8 *)buf, len,
17334 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017335
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017336 if (VOS_STATUS_SUCCESS != status)
17337 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17339 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017340 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017341 ret = -EINVAL;
17342 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017343 }
17344
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017345 if ((SIR_MAC_TDLS_DIS_REQ == action_code) ||
17346 (SIR_MAC_TDLS_DIS_RSP == action_code))
17347 {
17348 /* for DIS_REQ/DIS_RSP, supplicant don't consider the return status.
17349 * So we no need to wait for tdls_mgmt_comp for sending ack status.
17350 */
17351 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17352 "%s: tx done for frm %u", __func__, action_code);
17353 return 0;
17354 }
17355
17356 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17357 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
17358 WAIT_TIME_TDLS_MGMT);
17359
Hoonki Leed37cbb32013-04-20 00:31:14 -070017360 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
17361 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
17362
17363 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017364 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070017365 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070017366 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070017367 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017368 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080017369
17370 if (pHddCtx->isLogpInProgress)
17371 {
17372 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17373 "%s: LOGP in Progress. Ignore!!!", __func__);
17374 return -EAGAIN;
17375 }
Abhishek Singh837adf22015-10-01 17:37:37 +053017376 if (rc <= 0)
17377 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
17378 WLAN_LOG_INDICATOR_HOST_DRIVER,
17379 WLAN_LOG_REASON_HDD_TIME_OUT,
17380 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080017381
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017382 ret = -EINVAL;
17383 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017384 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017385 else
17386 {
17387 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17388 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
17389 __func__, rc, pAdapter->mgmtTxCompletionStatus);
17390 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017391
Gopichand Nakkala05922802013-03-14 12:23:19 -070017392 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070017393 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017394 ret = max_sta_failed;
17395 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070017396 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017397
Hoonki Leea34dd892013-02-05 22:56:02 -080017398 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
17399 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017400 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017401 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17402 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017403 }
17404 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
17405 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017406 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017407 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17408 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017409 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017410
17411 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017412
17413tx_failed:
17414 /* add_station will be called before sending TDLS_SETUP_REQ and
17415 * TDLS_SETUP_RSP and as part of add_station driver will enable
17416 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
17417 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
17418 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
17419 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
17420 */
17421
17422 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17423 (SIR_MAC_TDLS_SETUP_RSP == action_code))
17424 wlan_hdd_tdls_check_bmps(pAdapter);
17425 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017426}
17427
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017428#if TDLS_MGMT_VERSION2
17429static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17430 u8 *peer, u8 action_code, u8 dialog_token,
17431 u16 status_code, u32 peer_capability,
17432 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017433#else /* TDLS_MGMT_VERSION2 */
17434#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
17435static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17436 struct net_device *dev,
17437 const u8 *peer, u8 action_code,
17438 u8 dialog_token, u16 status_code,
17439 u32 peer_capability, bool initiator,
17440 const u8 *buf, size_t len)
17441#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17442static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17443 struct net_device *dev,
17444 const u8 *peer, u8 action_code,
17445 u8 dialog_token, u16 status_code,
17446 u32 peer_capability, const u8 *buf,
17447 size_t len)
17448#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
17449static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17450 struct net_device *dev,
17451 u8 *peer, u8 action_code,
17452 u8 dialog_token,
17453 u16 status_code, u32 peer_capability,
17454 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017455#else
17456static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17457 u8 *peer, u8 action_code, u8 dialog_token,
17458 u16 status_code, const u8 *buf, size_t len)
17459#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017460#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017461{
17462 int ret;
17463
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017464 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017465#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017466 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17467 dialog_token, status_code,
17468 peer_capability, buf, len);
17469#else /* TDLS_MGMT_VERSION2 */
17470#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17471 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17472 dialog_token, status_code,
17473 peer_capability, initiator,
17474 buf, len);
17475#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17476 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17477 dialog_token, status_code,
17478 peer_capability, buf, len);
17479#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17480 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17481 dialog_token, status_code,
17482 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017483#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017484 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17485 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017486#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017487#endif
17488 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017489
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017490 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017491}
Atul Mittal115287b2014-07-08 13:26:33 +053017492
17493int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017494#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17495 const u8 *peer,
17496#else
Atul Mittal115287b2014-07-08 13:26:33 +053017497 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017498#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017499 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053017500 cfg80211_exttdls_callback callback)
17501{
17502
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017503 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053017504 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017505 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053017506 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17507 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
17508 __func__, MAC_ADDR_ARRAY(peer));
17509
17510 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17511 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17512
17513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017514 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17515 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17516 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017517 return -ENOTSUPP;
17518 }
17519
17520 /* To cater the requirement of establishing the TDLS link
17521 * irrespective of the data traffic , get an entry of TDLS peer.
17522 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017523 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017524 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
17525 if (pTdlsPeer == NULL) {
17526 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17527 "%s: peer " MAC_ADDRESS_STR " not existing",
17528 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017529 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017530 return -EINVAL;
17531 }
17532
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017533 /* check FW TDLS Off Channel capability */
17534 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017535 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017536 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017537 {
17538 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
17539 pTdlsPeer->peerParams.global_operating_class =
17540 tdls_peer_params->global_operating_class;
17541 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
17542 pTdlsPeer->peerParams.min_bandwidth_kbps =
17543 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017544 /* check configured channel is valid, non dfs and
17545 * not current operating channel */
17546 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
17547 tdls_peer_params->channel)) &&
17548 (pHddStaCtx) &&
17549 (tdls_peer_params->channel !=
17550 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017551 {
17552 pTdlsPeer->isOffChannelConfigured = TRUE;
17553 }
17554 else
17555 {
17556 pTdlsPeer->isOffChannelConfigured = FALSE;
17557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17558 "%s: Configured Tdls Off Channel is not valid", __func__);
17559
17560 }
17561 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017562 "%s: tdls_off_channel %d isOffChannelConfigured %d "
17563 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017564 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017565 pTdlsPeer->isOffChannelConfigured,
17566 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017567 }
17568 else
17569 {
17570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017571 "%s: TDLS off channel FW capability %d, "
17572 "host capab %d or Invalid TDLS Peer Params", __func__,
17573 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
17574 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017575 }
17576
Atul Mittal115287b2014-07-08 13:26:33 +053017577 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
17578
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017579 mutex_unlock(&pHddCtx->tdls_lock);
17580
Atul Mittal115287b2014-07-08 13:26:33 +053017581 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17582 " %s TDLS Add Force Peer Failed",
17583 __func__);
17584 return -EINVAL;
17585 }
17586 /*EXT TDLS*/
17587
17588 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017589 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17591 " %s TDLS set callback Failed",
17592 __func__);
17593 return -EINVAL;
17594 }
17595
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017596 mutex_unlock(&pHddCtx->tdls_lock);
17597
Atul Mittal115287b2014-07-08 13:26:33 +053017598 return(0);
17599
17600}
17601
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017602int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
17603#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17604 const u8 *peer
17605#else
17606 u8 *peer
17607#endif
17608)
Atul Mittal115287b2014-07-08 13:26:33 +053017609{
17610
17611 hddTdlsPeer_t *pTdlsPeer;
17612 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17613 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17614 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
17615 __func__, MAC_ADDR_ARRAY(peer));
17616
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017617 if (0 != wlan_hdd_validate_context(pHddCtx)) {
17618 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
17619 return -EINVAL;
17620 }
17621
Atul Mittal115287b2014-07-08 13:26:33 +053017622 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17623 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17624
17625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017626 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17627 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17628 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017629 return -ENOTSUPP;
17630 }
17631
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017632 mutex_lock(&pHddCtx->tdls_lock);
17633 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053017634
17635 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017636 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017637 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017638 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053017639 __func__, MAC_ADDR_ARRAY(peer));
17640 return -EINVAL;
17641 }
17642 else {
17643 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
17644 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017645 /* if channel switch is configured, reset
17646 the channel for this peer */
17647 if (TRUE == pTdlsPeer->isOffChannelConfigured)
17648 {
17649 pTdlsPeer->peerParams.channel = 0;
17650 pTdlsPeer->isOffChannelConfigured = FALSE;
17651 }
Atul Mittal115287b2014-07-08 13:26:33 +053017652 }
17653
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017654 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017655 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017656 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053017657 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017658 }
Atul Mittal115287b2014-07-08 13:26:33 +053017659
17660 /*EXT TDLS*/
17661
17662 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017663 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017664 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17665 " %s TDLS set callback Failed",
17666 __func__);
17667 return -EINVAL;
17668 }
Atul Mittal115287b2014-07-08 13:26:33 +053017669
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017670 mutex_unlock(&pHddCtx->tdls_lock);
17671
17672 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053017673}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017674static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017675#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17676 const u8 *peer,
17677#else
17678 u8 *peer,
17679#endif
17680 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017681{
17682 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17683 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017684 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017685 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017686
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017687 ENTER();
17688
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017689 if (!pAdapter) {
17690 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
17691 return -EINVAL;
17692 }
17693
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017694 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17695 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
17696 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017697 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017698 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017699 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070017700 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017701 return -EINVAL;
17702 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017703
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017704 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017705 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017706 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017707 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017708 }
17709
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017710
17711 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017712 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017713 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017715 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
17716 "Cannot process TDLS commands",
17717 pHddCtx->cfg_ini->fEnableTDLSSupport,
17718 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017719 return -ENOTSUPP;
17720 }
17721
17722 switch (oper) {
17723 case NL80211_TDLS_ENABLE_LINK:
17724 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017725 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017726 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017727 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053017728 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017729 tANI_U16 numCurrTdlsPeers = 0;
17730 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017731 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017732
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017733 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17734 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
17735 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017736
Sunil Dutt41de4e22013-11-14 18:09:02 +053017737 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053017738 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053017739 if ( NULL == pTdlsPeer ) {
17740 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
17741 " (oper %d) not exsting. ignored",
17742 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
17743 return -EINVAL;
17744 }
17745
17746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17747 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
17748 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
17749 "NL80211_TDLS_ENABLE_LINK");
17750
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070017751 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
17752 {
17753 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
17754 MAC_ADDRESS_STR " failed",
17755 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
17756 return -EINVAL;
17757 }
17758
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053017759 /* before starting tdls connection, set tdls
17760 * off channel established status to default value */
17761 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017762 /* TDLS Off Channel, Disable tdls channel switch,
17763 when there are more than one tdls link */
17764 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053017765 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017766 {
17767 /* get connected peer and send disable tdls off chan */
17768 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017769 if ((connPeer) &&
17770 (connPeer->isOffChannelSupported == TRUE) &&
17771 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017772 {
17773 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17774 "%s: More then one peer connected, Disable "
17775 "TDLS channel switch", __func__);
17776
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053017777 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017778
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017779 ret = sme_SendTdlsChanSwitchReq(
17780 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017781 pAdapter->sessionId,
17782 connPeer->peerMac,
17783 connPeer->peerParams.channel,
17784 TDLS_OFF_CHANNEL_BW_OFFSET,
17785 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017786 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017787 hddLog(VOS_TRACE_LEVEL_ERROR,
17788 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017789 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017790 }
17791 else
17792 {
17793 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17794 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017795 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017796 "isOffChannelConfigured %d",
17797 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017798 (connPeer ? (connPeer->isOffChannelSupported)
17799 : -1),
17800 (connPeer ? (connPeer->isOffChannelConfigured)
17801 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017802 }
17803 }
17804
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017805 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017806 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017807 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053017808
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017809 if (0 != wlan_hdd_tdls_get_link_establish_params(
17810 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017812 return -EINVAL;
17813 }
17814 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017815
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017816 ret = sme_SendTdlsLinkEstablishParams(
17817 WLAN_HDD_GET_HAL_CTX(pAdapter),
17818 pAdapter->sessionId, peer,
17819 &tdlsLinkEstablishParams);
17820 if (ret != VOS_STATUS_SUCCESS) {
17821 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
17822 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017823 /* Send TDLS peer UAPSD capabilities to the firmware and
17824 * register with the TL on after the response for this operation
17825 * is received .
17826 */
17827 ret = wait_for_completion_interruptible_timeout(
17828 &pAdapter->tdls_link_establish_req_comp,
17829 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
17830 if (ret <= 0)
17831 {
17832 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017833 FL("Link Establish Request Failed Status %ld"),
17834 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017835 return -EINVAL;
17836 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017837 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017838
Atul Mittal115287b2014-07-08 13:26:33 +053017839 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
17840 eTDLS_LINK_CONNECTED,
17841 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053017842 staDesc.ucSTAId = pTdlsPeer->staId;
17843 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017844 ret = WLANTL_UpdateTdlsSTAClient(
17845 pHddCtx->pvosContext,
17846 &staDesc);
17847 if (ret != VOS_STATUS_SUCCESS) {
17848 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
17849 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053017850
Gopichand Nakkala471708b2013-06-04 20:03:01 +053017851 /* Mark TDLS client Authenticated .*/
17852 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
17853 pTdlsPeer->staId,
17854 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070017855 if (VOS_STATUS_SUCCESS == status)
17856 {
Hoonki Lee14621352013-04-16 17:51:19 -070017857 if (pTdlsPeer->is_responder == 0)
17858 {
17859 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053017860 tdlsConnInfo_t *tdlsInfo;
17861
17862 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
17863
17864 /* Initialize initiator wait callback */
17865 vos_timer_init(
17866 &pTdlsPeer->initiatorWaitTimeoutTimer,
17867 VOS_TIMER_TYPE_SW,
17868 wlan_hdd_tdls_initiator_wait_cb,
17869 tdlsInfo);
Hoonki Lee14621352013-04-16 17:51:19 -070017870
17871 wlan_hdd_tdls_timer_restart(pAdapter,
17872 &pTdlsPeer->initiatorWaitTimeoutTimer,
17873 WAIT_TIME_TDLS_INITIATOR);
17874 /* suspend initiator TX until it receives direct packet from the
17875 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017876 ret = WLANTL_SuspendDataTx(
17877 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
17878 &staId, NULL);
17879 if (ret != VOS_STATUS_SUCCESS) {
17880 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
17881 }
Hoonki Lee14621352013-04-16 17:51:19 -070017882 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017883
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017884 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017885 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017886 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017887 suppChannelLen =
17888 tdlsLinkEstablishParams.supportedChannelsLen;
17889
17890 if ((suppChannelLen > 0) &&
17891 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
17892 {
17893 tANI_U8 suppPeerChannel = 0;
17894 int i = 0;
17895 for (i = 0U; i < suppChannelLen; i++)
17896 {
17897 suppPeerChannel =
17898 tdlsLinkEstablishParams.supportedChannels[i];
17899
17900 pTdlsPeer->isOffChannelSupported = FALSE;
17901 if (suppPeerChannel ==
17902 pTdlsPeer->peerParams.channel)
17903 {
17904 pTdlsPeer->isOffChannelSupported = TRUE;
17905 break;
17906 }
17907 }
17908 }
17909 else
17910 {
17911 pTdlsPeer->isOffChannelSupported = FALSE;
17912 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017913 }
17914 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17915 "%s: TDLS channel switch request for channel "
17916 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017917 "%d isOffChannelSupported %d", __func__,
17918 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017919 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017920 suppChannelLen,
17921 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017922
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017923 /* TDLS Off Channel, Enable tdls channel switch,
17924 when their is only one tdls link and it supports */
17925 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17926 if ((numCurrTdlsPeers == 1) &&
17927 (TRUE == pTdlsPeer->isOffChannelSupported) &&
17928 (TRUE == pTdlsPeer->isOffChannelConfigured))
17929 {
17930 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17931 "%s: Send TDLS channel switch request for channel %d",
17932 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053017933
17934 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017935 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
17936 pAdapter->sessionId,
17937 pTdlsPeer->peerMac,
17938 pTdlsPeer->peerParams.channel,
17939 TDLS_OFF_CHANNEL_BW_OFFSET,
17940 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017941 if (ret != VOS_STATUS_SUCCESS) {
17942 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
17943 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017944 }
17945 else
17946 {
17947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17948 "%s: TDLS channel switch request not sent"
17949 " numCurrTdlsPeers %d "
17950 "isOffChannelSupported %d "
17951 "isOffChannelConfigured %d",
17952 __func__, numCurrTdlsPeers,
17953 pTdlsPeer->isOffChannelSupported,
17954 pTdlsPeer->isOffChannelConfigured);
17955 }
17956
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070017957 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017958 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017959
17960 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053017961 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
17962 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017963 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053017964 int ac;
17965 uint8 ucAc[4] = { WLANTL_AC_VO,
17966 WLANTL_AC_VI,
17967 WLANTL_AC_BK,
17968 WLANTL_AC_BE };
17969 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
17970 for(ac=0; ac < 4; ac++)
17971 {
17972 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
17973 pTdlsPeer->staId, ucAc[ac],
17974 tlTid[ac], tlTid[ac], 0, 0,
17975 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017976 if (status != VOS_STATUS_SUCCESS) {
17977 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
17978 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053017979 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017980 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017981 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017982 }
17983 break;
17984 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080017985 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017986 tANI_U16 numCurrTdlsPeers = 0;
17987 hddTdlsPeer_t *connPeer = NULL;
17988
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017989 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17990 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
17991 __func__, MAC_ADDR_ARRAY(peer));
17992
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053017993 mutex_lock(&pHddCtx->tdls_lock);
17994 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053017995
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017996
Sunil Dutt41de4e22013-11-14 18:09:02 +053017997 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053017998 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053017999 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18000 " (oper %d) not exsting. ignored",
18001 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
18002 return -EINVAL;
18003 }
18004
18005 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18006 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
18007 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
18008 "NL80211_TDLS_DISABLE_LINK");
18009
Hoonki Lee5305c3a2013-04-29 23:28:59 -070018010 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080018011 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018012 long status;
18013
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053018014 /* set tdls off channel status to false for this peer */
18015 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053018016 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
18017 eTDLS_LINK_TEARING,
18018 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
18019 eTDLS_LINK_UNSPECIFIED:
18020 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018021 mutex_unlock(&pHddCtx->tdls_lock);
18022
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018023 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
18024
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018025 status = sme_DeleteTdlsPeerSta(
18026 WLAN_HDD_GET_HAL_CTX(pAdapter),
18027 pAdapter->sessionId, peer );
18028 if (status != VOS_STATUS_SUCCESS) {
18029 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
18030 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018031
18032 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
18033 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018034
18035 mutex_lock(&pHddCtx->tdls_lock);
18036 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
18037 if ( NULL == pTdlsPeer ) {
18038 mutex_unlock(&pHddCtx->tdls_lock);
18039 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
18040 " peer was freed in other context",
18041 __func__, MAC_ADDR_ARRAY(peer));
18042 return -EINVAL;
18043 }
18044
Atul Mittal271a7652014-09-12 13:18:22 +053018045 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053018046 eTDLS_LINK_IDLE,
18047 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018048 mutex_unlock(&pHddCtx->tdls_lock);
18049
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018050 if (status <= 0)
18051 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018052 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18053 "%s: Del station failed status %ld",
18054 __func__, status);
18055 return -EPERM;
18056 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018057
18058 /* TDLS Off Channel, Enable tdls channel switch,
18059 when their is only one tdls link and it supports */
18060 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18061 if (numCurrTdlsPeers == 1)
18062 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018063 tSirMacAddr peerMac;
18064 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018065
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018066 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018067 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018068
18069 if (connPeer == NULL) {
18070 mutex_unlock(&pHddCtx->tdls_lock);
18071 hddLog(VOS_TRACE_LEVEL_ERROR,
18072 "%s connPeer is NULL", __func__);
18073 return -EINVAL;
18074 }
18075
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018076 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
18077 channel = connPeer->peerParams.channel;
18078
18079 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18080 "%s: TDLS channel switch "
18081 "isOffChannelSupported %d "
18082 "isOffChannelConfigured %d "
18083 "isOffChannelEstablished %d",
18084 __func__,
18085 (connPeer ? connPeer->isOffChannelSupported : -1),
18086 (connPeer ? connPeer->isOffChannelConfigured : -1),
18087 (connPeer ? connPeer->isOffChannelEstablished : -1));
18088
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018089 if ((connPeer) &&
18090 (connPeer->isOffChannelSupported == TRUE) &&
18091 (connPeer->isOffChannelConfigured == TRUE))
18092 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018093 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018094 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018095 status = sme_SendTdlsChanSwitchReq(
18096 WLAN_HDD_GET_HAL_CTX(pAdapter),
18097 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018098 peerMac,
18099 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018100 TDLS_OFF_CHANNEL_BW_OFFSET,
18101 TDLS_CHANNEL_SWITCH_ENABLE);
18102 if (status != VOS_STATUS_SUCCESS) {
18103 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
18104 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018105 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018106 else
18107 mutex_unlock(&pHddCtx->tdls_lock);
18108 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018109 else
18110 {
18111 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18112 "%s: TDLS channel switch request not sent "
18113 "numCurrTdlsPeers %d ",
18114 __func__, numCurrTdlsPeers);
18115 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018116 }
18117 else
18118 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018119 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018120 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18121 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080018122 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018123 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018124 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018125 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018126 {
Atul Mittal115287b2014-07-08 13:26:33 +053018127 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018128
Atul Mittal115287b2014-07-08 13:26:33 +053018129 if (0 != status)
18130 {
18131 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018132 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053018133 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018134 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053018135 break;
18136 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018137 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018138 {
Atul Mittal115287b2014-07-08 13:26:33 +053018139 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
18140 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018141 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053018142 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018143
Atul Mittal115287b2014-07-08 13:26:33 +053018144 if (0 != status)
18145 {
18146 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018147 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053018148 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053018149 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053018150 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018151 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018152 case NL80211_TDLS_DISCOVERY_REQ:
18153 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018154 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018155 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018156 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018157 return -ENOTSUPP;
18158 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018159 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18160 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018161 return -ENOTSUPP;
18162 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018163
18164 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018165 return 0;
18166}
Chilam NG571c65a2013-01-19 12:27:36 +053018167
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018168static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018169#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18170 const u8 *peer,
18171#else
18172 u8 *peer,
18173#endif
18174 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018175{
18176 int ret;
18177
18178 vos_ssr_protect(__func__);
18179 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
18180 vos_ssr_unprotect(__func__);
18181
18182 return ret;
18183}
18184
Chilam NG571c65a2013-01-19 12:27:36 +053018185int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
18186 struct net_device *dev, u8 *peer)
18187{
Arif Hussaina7c8e412013-11-20 11:06:42 -080018188 hddLog(VOS_TRACE_LEVEL_INFO,
18189 "tdls send discover req: "MAC_ADDRESS_STR,
18190 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053018191
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018192#if TDLS_MGMT_VERSION2
18193 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18194 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18195#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018196#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18197 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18198 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
18199#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18200 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18201 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18202#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18203 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18204 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18205#else
Chilam NG571c65a2013-01-19 12:27:36 +053018206 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18207 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018208#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018209#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053018210}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018211#endif
18212
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018213#ifdef WLAN_FEATURE_GTK_OFFLOAD
18214/*
18215 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
18216 * Callback rountine called upon receiving response for
18217 * get offload info
18218 */
18219void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
18220 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
18221{
18222
18223 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018224 tANI_U8 tempReplayCounter[8];
18225 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018226
18227 ENTER();
18228
18229 if (NULL == pAdapter)
18230 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018231 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018232 "%s: HDD adapter is Null", __func__);
18233 return ;
18234 }
18235
18236 if (NULL == pGtkOffloadGetInfoRsp)
18237 {
18238 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18239 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
18240 return ;
18241 }
18242
18243 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
18244 {
18245 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18246 "%s: wlan Failed to get replay counter value",
18247 __func__);
18248 return ;
18249 }
18250
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018251 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18252 /* Update replay counter */
18253 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
18254 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18255
18256 {
18257 /* changing from little to big endian since supplicant
18258 * works on big endian format
18259 */
18260 int i;
18261 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18262
18263 for (i = 0; i < 8; i++)
18264 {
18265 tempReplayCounter[7-i] = (tANI_U8)p[i];
18266 }
18267 }
18268
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018269 /* Update replay counter to NL */
18270 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018271 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018272}
18273
18274/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018275 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018276 * This function is used to offload GTK rekeying job to the firmware.
18277 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018278int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018279 struct cfg80211_gtk_rekey_data *data)
18280{
18281 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18282 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
18283 hdd_station_ctx_t *pHddStaCtx;
18284 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018285 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018286 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018287 eHalStatus status = eHAL_STATUS_FAILURE;
18288
18289 ENTER();
18290
18291 if (NULL == pAdapter)
18292 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018293 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018294 "%s: HDD adapter is Null", __func__);
18295 return -ENODEV;
18296 }
18297
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018298 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18299 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
18300 pAdapter->sessionId, pAdapter->device_mode));
18301
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018302 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018303 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018304 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018305 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018306 }
18307
18308 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18309 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18310 if (NULL == hHal)
18311 {
18312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18313 "%s: HAL context is Null!!!", __func__);
18314 return -EAGAIN;
18315 }
18316
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018317 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
18318 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
18319 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
18320 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018321 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018322 {
18323 /* changing from big to little endian since driver
18324 * works on little endian format
18325 */
18326 tANI_U8 *p =
18327 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
18328 int i;
18329
18330 for (i = 0; i < 8; i++)
18331 {
18332 p[7-i] = data->replay_ctr[i];
18333 }
18334 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018335
18336 if (TRUE == pHddCtx->hdd_wlan_suspended)
18337 {
18338 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018339 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
18340 sizeof (tSirGtkOffloadParams));
18341 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018342 pAdapter->sessionId);
18343
18344 if (eHAL_STATUS_SUCCESS != status)
18345 {
18346 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18347 "%s: sme_SetGTKOffload failed, returned %d",
18348 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018349
18350 /* Need to clear any trace of key value in the memory.
18351 * Thus zero out the memory even though it is local
18352 * variable.
18353 */
18354 vos_mem_zero(&hddGtkOffloadReqParams,
18355 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018356 return status;
18357 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18359 "%s: sme_SetGTKOffload successfull", __func__);
18360 }
18361 else
18362 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018363 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18364 "%s: wlan not suspended GTKOffload request is stored",
18365 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018366 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018367
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018368 /* Need to clear any trace of key value in the memory.
18369 * Thus zero out the memory even though it is local
18370 * variable.
18371 */
18372 vos_mem_zero(&hddGtkOffloadReqParams,
18373 sizeof(hddGtkOffloadReqParams));
18374
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018375 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018376 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018377}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018378
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018379int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
18380 struct cfg80211_gtk_rekey_data *data)
18381{
18382 int ret;
18383
18384 vos_ssr_protect(__func__);
18385 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
18386 vos_ssr_unprotect(__func__);
18387
18388 return ret;
18389}
18390#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018391/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018392 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018393 * This function is used to set access control policy
18394 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018395static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18396 struct net_device *dev,
18397 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018398{
18399 int i;
18400 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18401 hdd_hostapd_state_t *pHostapdState;
18402 tsap_Config_t *pConfig;
18403 v_CONTEXT_t pVosContext = NULL;
18404 hdd_context_t *pHddCtx;
18405 int status;
18406
18407 ENTER();
18408
18409 if (NULL == pAdapter)
18410 {
18411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18412 "%s: HDD adapter is Null", __func__);
18413 return -ENODEV;
18414 }
18415
18416 if (NULL == params)
18417 {
18418 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18419 "%s: params is Null", __func__);
18420 return -EINVAL;
18421 }
18422
18423 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18424 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018425 if (0 != status)
18426 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018427 return status;
18428 }
18429
18430 pVosContext = pHddCtx->pvosContext;
18431 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
18432
18433 if (NULL == pHostapdState)
18434 {
18435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18436 "%s: pHostapdState is Null", __func__);
18437 return -EINVAL;
18438 }
18439
18440 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
18441 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018442 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18443 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
18444 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018445
18446 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
18447 {
18448 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
18449
18450 /* default value */
18451 pConfig->num_accept_mac = 0;
18452 pConfig->num_deny_mac = 0;
18453
18454 /**
18455 * access control policy
18456 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
18457 * listed in hostapd.deny file.
18458 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
18459 * listed in hostapd.accept file.
18460 */
18461 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
18462 {
18463 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
18464 }
18465 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
18466 {
18467 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
18468 }
18469 else
18470 {
18471 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18472 "%s:Acl Policy : %d is not supported",
18473 __func__, params->acl_policy);
18474 return -ENOTSUPP;
18475 }
18476
18477 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
18478 {
18479 pConfig->num_accept_mac = params->n_acl_entries;
18480 for (i = 0; i < params->n_acl_entries; i++)
18481 {
18482 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18483 "** Add ACL MAC entry %i in WhiletList :"
18484 MAC_ADDRESS_STR, i,
18485 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18486
18487 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
18488 sizeof(qcmacaddr));
18489 }
18490 }
18491 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
18492 {
18493 pConfig->num_deny_mac = params->n_acl_entries;
18494 for (i = 0; i < params->n_acl_entries; i++)
18495 {
18496 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18497 "** Add ACL MAC entry %i in BlackList :"
18498 MAC_ADDRESS_STR, i,
18499 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18500
18501 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
18502 sizeof(qcmacaddr));
18503 }
18504 }
18505
18506 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
18507 {
18508 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18509 "%s: SAP Set Mac Acl fail", __func__);
18510 return -EINVAL;
18511 }
18512 }
18513 else
18514 {
18515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053018516 "%s: Invalid device_mode = %s (%d)",
18517 __func__, hdd_device_modetoString(pAdapter->device_mode),
18518 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018519 return -EINVAL;
18520 }
18521
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018522 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018523 return 0;
18524}
18525
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018526static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18527 struct net_device *dev,
18528 const struct cfg80211_acl_data *params)
18529{
18530 int ret;
18531 vos_ssr_protect(__func__);
18532 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
18533 vos_ssr_unprotect(__func__);
18534
18535 return ret;
18536}
18537
Leo Chang9056f462013-08-01 19:21:11 -070018538#ifdef WLAN_NL80211_TESTMODE
18539#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070018540void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070018541(
18542 void *pAdapter,
18543 void *indCont
18544)
18545{
Leo Changd9df8aa2013-09-26 13:32:26 -070018546 tSirLPHBInd *lphbInd;
18547 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053018548 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070018549
18550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070018551 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070018552
c_hpothu73f35e62014-04-18 13:40:08 +053018553 if (pAdapter == NULL)
18554 {
18555 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18556 "%s: pAdapter is NULL\n",__func__);
18557 return;
18558 }
18559
Leo Chang9056f462013-08-01 19:21:11 -070018560 if (NULL == indCont)
18561 {
18562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070018563 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070018564 return;
18565 }
18566
c_hpothu73f35e62014-04-18 13:40:08 +053018567 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070018568 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070018569 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053018570 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070018571 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070018572 GFP_ATOMIC);
18573 if (!skb)
18574 {
18575 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18576 "LPHB timeout, NL buffer alloc fail");
18577 return;
18578 }
18579
Leo Changac3ba772013-10-07 09:47:04 -070018580 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070018581 {
18582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18583 "WLAN_HDD_TM_ATTR_CMD put fail");
18584 goto nla_put_failure;
18585 }
Leo Changac3ba772013-10-07 09:47:04 -070018586 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070018587 {
18588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18589 "WLAN_HDD_TM_ATTR_TYPE put fail");
18590 goto nla_put_failure;
18591 }
Leo Changac3ba772013-10-07 09:47:04 -070018592 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070018593 sizeof(tSirLPHBInd), lphbInd))
18594 {
18595 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18596 "WLAN_HDD_TM_ATTR_DATA put fail");
18597 goto nla_put_failure;
18598 }
Leo Chang9056f462013-08-01 19:21:11 -070018599 cfg80211_testmode_event(skb, GFP_ATOMIC);
18600 return;
18601
18602nla_put_failure:
18603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18604 "NLA Put fail");
18605 kfree_skb(skb);
18606
18607 return;
18608}
18609#endif /* FEATURE_WLAN_LPHB */
18610
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018611static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070018612{
18613 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
18614 int err = 0;
18615#ifdef FEATURE_WLAN_LPHB
18616 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070018617 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018618
18619 ENTER();
18620
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018621 err = wlan_hdd_validate_context(pHddCtx);
18622 if (0 != err)
18623 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018624 return err;
18625 }
Leo Chang9056f462013-08-01 19:21:11 -070018626#endif /* FEATURE_WLAN_LPHB */
18627
18628 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
18629 if (err)
18630 {
18631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18632 "%s Testmode INV ATTR", __func__);
18633 return err;
18634 }
18635
18636 if (!tb[WLAN_HDD_TM_ATTR_CMD])
18637 {
18638 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18639 "%s Testmode INV CMD", __func__);
18640 return -EINVAL;
18641 }
18642
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018643 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18644 TRACE_CODE_HDD_CFG80211_TESTMODE,
18645 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070018646 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
18647 {
18648#ifdef FEATURE_WLAN_LPHB
18649 /* Low Power Heartbeat configuration request */
18650 case WLAN_HDD_TM_CMD_WLAN_HB:
18651 {
18652 int buf_len;
18653 void *buf;
18654 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080018655 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070018656
18657 if (!tb[WLAN_HDD_TM_ATTR_DATA])
18658 {
18659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18660 "%s Testmode INV DATA", __func__);
18661 return -EINVAL;
18662 }
18663
18664 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
18665 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080018666
18667 hb_params_temp =(tSirLPHBReq *)buf;
18668 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
18669 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
18670 return -EINVAL;
18671
Leo Chang9056f462013-08-01 19:21:11 -070018672 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
18673 if (NULL == hb_params)
18674 {
18675 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18676 "%s Request Buffer Alloc Fail", __func__);
18677 return -EINVAL;
18678 }
18679
18680 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070018681 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
18682 hb_params,
18683 wlan_hdd_cfg80211_lphb_ind_handler);
18684 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070018685 {
Leo Changd9df8aa2013-09-26 13:32:26 -070018686 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18687 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070018688 vos_mem_free(hb_params);
18689 }
Leo Chang9056f462013-08-01 19:21:11 -070018690 return 0;
18691 }
18692#endif /* FEATURE_WLAN_LPHB */
18693 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018694 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18695 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070018696 return -EOPNOTSUPP;
18697 }
18698
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018699 EXIT();
18700 return err;
Leo Chang9056f462013-08-01 19:21:11 -070018701}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018702
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053018703static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
18704#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
18705 struct wireless_dev *wdev,
18706#endif
18707 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018708{
18709 int ret;
18710
18711 vos_ssr_protect(__func__);
18712 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
18713 vos_ssr_unprotect(__func__);
18714
18715 return ret;
18716}
Leo Chang9056f462013-08-01 19:21:11 -070018717#endif /* CONFIG_NL80211_TESTMODE */
18718
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018719static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018720 struct net_device *dev,
18721 int idx, struct survey_info *survey)
18722{
18723 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18724 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053018725 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018726 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053018727 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018728 v_S7_t snr,rssi;
18729 int status, i, j, filled = 0;
18730
18731 ENTER();
18732
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018733 if (NULL == pAdapter)
18734 {
18735 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18736 "%s: HDD adapter is Null", __func__);
18737 return -ENODEV;
18738 }
18739
18740 if (NULL == wiphy)
18741 {
18742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18743 "%s: wiphy is Null", __func__);
18744 return -ENODEV;
18745 }
18746
18747 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18748 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018749 if (0 != status)
18750 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018751 return status;
18752 }
18753
Mihir Sheted9072e02013-08-21 17:02:29 +053018754 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18755
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018756 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053018757 0 != pAdapter->survey_idx ||
18758 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018759 {
18760 /* The survey dump ops when implemented completely is expected to
18761 * return a survey of all channels and the ops is called by the
18762 * kernel with incremental values of the argument 'idx' till it
18763 * returns -ENONET. But we can only support the survey for the
18764 * operating channel for now. survey_idx is used to track
18765 * that the ops is called only once and then return -ENONET for
18766 * the next iteration
18767 */
18768 pAdapter->survey_idx = 0;
18769 return -ENONET;
18770 }
18771
Mukul Sharma9d5233b2015-06-11 20:28:20 +053018772 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
18773 {
18774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18775 "%s: Roaming in progress, hence return ", __func__);
18776 return -ENONET;
18777 }
18778
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018779 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18780
18781 wlan_hdd_get_snr(pAdapter, &snr);
18782 wlan_hdd_get_rssi(pAdapter, &rssi);
18783
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018784 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18785 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
18786 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018787 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
18788 hdd_wlan_get_freq(channel, &freq);
18789
18790
18791 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
18792 {
18793 if (NULL == wiphy->bands[i])
18794 {
18795 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
18796 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
18797 continue;
18798 }
18799
18800 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
18801 {
18802 struct ieee80211_supported_band *band = wiphy->bands[i];
18803
18804 if (band->channels[j].center_freq == (v_U16_t)freq)
18805 {
18806 survey->channel = &band->channels[j];
18807 /* The Rx BDs contain SNR values in dB for the received frames
18808 * while the supplicant expects noise. So we calculate and
18809 * return the value of noise (dBm)
18810 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
18811 */
18812 survey->noise = rssi - snr;
18813 survey->filled = SURVEY_INFO_NOISE_DBM;
18814 filled = 1;
18815 }
18816 }
18817 }
18818
18819 if (filled)
18820 pAdapter->survey_idx = 1;
18821 else
18822 {
18823 pAdapter->survey_idx = 0;
18824 return -ENONET;
18825 }
18826
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018827 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018828 return 0;
18829}
18830
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018831static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
18832 struct net_device *dev,
18833 int idx, struct survey_info *survey)
18834{
18835 int ret;
18836
18837 vos_ssr_protect(__func__);
18838 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
18839 vos_ssr_unprotect(__func__);
18840
18841 return ret;
18842}
18843
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018844/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018845 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018846 * this is called when cfg80211 driver resume
18847 * driver updates latest sched_scan scan result(if any) to cfg80211 database
18848 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018849int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018850{
18851 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
18852 hdd_adapter_t *pAdapter;
18853 hdd_adapter_list_node_t *pAdapterNode, *pNext;
18854 VOS_STATUS status = VOS_STATUS_SUCCESS;
18855
18856 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018857
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018858 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018859 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018860 return 0;
18861 }
18862
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018863 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
18864 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018865 spin_lock(&pHddCtx->schedScan_lock);
18866 pHddCtx->isWiphySuspended = FALSE;
18867 if (TRUE != pHddCtx->isSchedScanUpdatePending)
18868 {
18869 spin_unlock(&pHddCtx->schedScan_lock);
18870 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18871 "%s: Return resume is not due to PNO indication", __func__);
18872 return 0;
18873 }
18874 // Reset flag to avoid updatating cfg80211 data old results again
18875 pHddCtx->isSchedScanUpdatePending = FALSE;
18876 spin_unlock(&pHddCtx->schedScan_lock);
18877
18878 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
18879
18880 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
18881 {
18882 pAdapter = pAdapterNode->pAdapter;
18883 if ( (NULL != pAdapter) &&
18884 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
18885 {
18886 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018887 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018888 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
18889 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018890 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018891 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018892 {
18893 /* Acquire wakelock to handle the case where APP's tries to
18894 * suspend immediately after updating the scan results. Whis
18895 * results in app's is in suspended state and not able to
18896 * process the connect request to AP
18897 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053018898 hdd_prevent_suspend_timeout(2000,
18899 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018900 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018901 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018902
18903 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18904 "%s : cfg80211 scan result database updated", __func__);
18905
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018906 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018907 return 0;
18908
18909 }
18910 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
18911 pAdapterNode = pNext;
18912 }
18913
18914 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18915 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018916 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018917 return 0;
18918}
18919
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018920int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
18921{
18922 int ret;
18923
18924 vos_ssr_protect(__func__);
18925 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
18926 vos_ssr_unprotect(__func__);
18927
18928 return ret;
18929}
18930
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018931/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018932 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018933 * this is called when cfg80211 driver suspends
18934 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018935int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018936 struct cfg80211_wowlan *wow)
18937{
18938 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018939 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018940
18941 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018942
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018943 ret = wlan_hdd_validate_context(pHddCtx);
18944 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018945 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018946 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018947 }
18948
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018949
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018950 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18951 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
18952 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018953 pHddCtx->isWiphySuspended = TRUE;
18954
18955 EXIT();
18956
18957 return 0;
18958}
18959
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018960int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
18961 struct cfg80211_wowlan *wow)
18962{
18963 int ret;
18964
18965 vos_ssr_protect(__func__);
18966 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
18967 vos_ssr_unprotect(__func__);
18968
18969 return ret;
18970}
Jeff Johnson295189b2012-06-20 16:38:30 -070018971/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018972static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070018973{
18974 .add_virtual_intf = wlan_hdd_add_virtual_intf,
18975 .del_virtual_intf = wlan_hdd_del_virtual_intf,
18976 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
18977 .change_station = wlan_hdd_change_station,
18978#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
18979 .add_beacon = wlan_hdd_cfg80211_add_beacon,
18980 .del_beacon = wlan_hdd_cfg80211_del_beacon,
18981 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018982#else
18983 .start_ap = wlan_hdd_cfg80211_start_ap,
18984 .change_beacon = wlan_hdd_cfg80211_change_beacon,
18985 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070018986#endif
18987 .change_bss = wlan_hdd_cfg80211_change_bss,
18988 .add_key = wlan_hdd_cfg80211_add_key,
18989 .get_key = wlan_hdd_cfg80211_get_key,
18990 .del_key = wlan_hdd_cfg80211_del_key,
18991 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080018992#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070018993 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080018994#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018995 .scan = wlan_hdd_cfg80211_scan,
18996 .connect = wlan_hdd_cfg80211_connect,
18997 .disconnect = wlan_hdd_cfg80211_disconnect,
18998 .join_ibss = wlan_hdd_cfg80211_join_ibss,
18999 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
19000 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
19001 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
19002 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070019003 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
19004 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053019005 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070019006#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
19007 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
19008 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
19009 .set_txq_params = wlan_hdd_set_txq_params,
19010#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070019011 .get_station = wlan_hdd_cfg80211_get_station,
19012 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
19013 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070019014 .add_station = wlan_hdd_cfg80211_add_station,
19015#ifdef FEATURE_WLAN_LFR
19016 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
19017 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
19018 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
19019#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070019020#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
19021 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
19022#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080019023#ifdef FEATURE_WLAN_TDLS
19024 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
19025 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
19026#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053019027#ifdef WLAN_FEATURE_GTK_OFFLOAD
19028 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
19029#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053019030#ifdef FEATURE_WLAN_SCAN_PNO
19031 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
19032 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
19033#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053019034 .resume = wlan_hdd_cfg80211_resume_wlan,
19035 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053019036 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070019037#ifdef WLAN_NL80211_TESTMODE
19038 .testmode_cmd = wlan_hdd_cfg80211_testmode,
19039#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053019040 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070019041};
19042