blob: 07099c6d499bc56a9f16da2fd42ca3ea93f97e9d [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053098#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +053099#include "wlan_logging_sock_svc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530100
Jeff Johnson295189b2012-06-20 16:38:30 -0700101
102#define g_mode_rates_size (12)
103#define a_mode_rates_size (8)
104#define FREQ_BASE_80211G (2407)
105#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700106#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530107#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800109 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700110
111#define HDD2GHZCHAN(freq, chan, flag) { \
112 .band = IEEE80211_BAND_2GHZ, \
113 .center_freq = (freq), \
114 .hw_value = (chan),\
115 .flags = (flag), \
116 .max_antenna_gain = 0 ,\
117 .max_power = 30, \
118}
119
120#define HDD5GHZCHAN(freq, chan, flag) { \
121 .band = IEEE80211_BAND_5GHZ, \
122 .center_freq = (freq), \
123 .hw_value = (chan),\
124 .flags = (flag), \
125 .max_antenna_gain = 0 ,\
126 .max_power = 30, \
127}
128
129#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
130{\
131 .bitrate = rate, \
132 .hw_value = rate_id, \
133 .flags = flag, \
134}
135
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530136#ifdef WLAN_FEATURE_VOWIFI_11R
137#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
138#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
139#endif
140
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530141#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530142#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530143
Sunil Duttc69bccb2014-05-26 21:30:20 +0530144#ifdef WLAN_FEATURE_LINK_LAYER_STATS
145/*
146 * Used to allocate the size of 4096 for the link layer stats.
147 * The size of 4096 is considered assuming that all data per
148 * respective event fit with in the limit.Please take a call
149 * on the limit based on the data requirements on link layer
150 * statistics.
151 */
152#define LL_STATS_EVENT_BUF_SIZE 4096
153#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530154#ifdef WLAN_FEATURE_EXTSCAN
155/*
156 * Used to allocate the size of 4096 for the EXTScan NL data.
157 * The size of 4096 is considered assuming that all data per
158 * respective event fit with in the limit.Please take a call
159 * on the limit based on the data requirements.
160 */
161
162#define EXTSCAN_EVENT_BUF_SIZE 4096
163#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
164#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530165
Atul Mittal115287b2014-07-08 13:26:33 +0530166/*EXT TDLS*/
167/*
168 * Used to allocate the size of 4096 for the TDLS.
169 * The size of 4096 is considered assuming that all data per
170 * respective event fit with in the limit.Please take a call
171 * on the limit based on the data requirements on link layer
172 * statistics.
173 */
174#define EXTTDLS_EVENT_BUF_SIZE 4096
175
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530176static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700177{
178 WLAN_CIPHER_SUITE_WEP40,
179 WLAN_CIPHER_SUITE_WEP104,
180 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800181#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700182#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
183 WLAN_CIPHER_SUITE_KRK,
184 WLAN_CIPHER_SUITE_CCMP,
185#else
186 WLAN_CIPHER_SUITE_CCMP,
187#endif
188#ifdef FEATURE_WLAN_WAPI
189 WLAN_CIPHER_SUITE_SMS4,
190#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700191#ifdef WLAN_FEATURE_11W
192 WLAN_CIPHER_SUITE_AES_CMAC,
193#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700194};
195
196static inline int is_broadcast_ether_addr(const u8 *addr)
197{
198 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
199 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
200}
201
202static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530203{
Jeff Johnson295189b2012-06-20 16:38:30 -0700204 HDD2GHZCHAN(2412, 1, 0) ,
205 HDD2GHZCHAN(2417, 2, 0) ,
206 HDD2GHZCHAN(2422, 3, 0) ,
207 HDD2GHZCHAN(2427, 4, 0) ,
208 HDD2GHZCHAN(2432, 5, 0) ,
209 HDD2GHZCHAN(2437, 6, 0) ,
210 HDD2GHZCHAN(2442, 7, 0) ,
211 HDD2GHZCHAN(2447, 8, 0) ,
212 HDD2GHZCHAN(2452, 9, 0) ,
213 HDD2GHZCHAN(2457, 10, 0) ,
214 HDD2GHZCHAN(2462, 11, 0) ,
215 HDD2GHZCHAN(2467, 12, 0) ,
216 HDD2GHZCHAN(2472, 13, 0) ,
217 HDD2GHZCHAN(2484, 14, 0) ,
218};
219
Jeff Johnson295189b2012-06-20 16:38:30 -0700220static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
221{
222 HDD2GHZCHAN(2412, 1, 0) ,
223 HDD2GHZCHAN(2437, 6, 0) ,
224 HDD2GHZCHAN(2462, 11, 0) ,
225};
Jeff Johnson295189b2012-06-20 16:38:30 -0700226
227static struct ieee80211_channel hdd_channels_5_GHZ[] =
228{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700229 HDD5GHZCHAN(4920, 240, 0) ,
230 HDD5GHZCHAN(4940, 244, 0) ,
231 HDD5GHZCHAN(4960, 248, 0) ,
232 HDD5GHZCHAN(4980, 252, 0) ,
233 HDD5GHZCHAN(5040, 208, 0) ,
234 HDD5GHZCHAN(5060, 212, 0) ,
235 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700236 HDD5GHZCHAN(5180, 36, 0) ,
237 HDD5GHZCHAN(5200, 40, 0) ,
238 HDD5GHZCHAN(5220, 44, 0) ,
239 HDD5GHZCHAN(5240, 48, 0) ,
240 HDD5GHZCHAN(5260, 52, 0) ,
241 HDD5GHZCHAN(5280, 56, 0) ,
242 HDD5GHZCHAN(5300, 60, 0) ,
243 HDD5GHZCHAN(5320, 64, 0) ,
244 HDD5GHZCHAN(5500,100, 0) ,
245 HDD5GHZCHAN(5520,104, 0) ,
246 HDD5GHZCHAN(5540,108, 0) ,
247 HDD5GHZCHAN(5560,112, 0) ,
248 HDD5GHZCHAN(5580,116, 0) ,
249 HDD5GHZCHAN(5600,120, 0) ,
250 HDD5GHZCHAN(5620,124, 0) ,
251 HDD5GHZCHAN(5640,128, 0) ,
252 HDD5GHZCHAN(5660,132, 0) ,
253 HDD5GHZCHAN(5680,136, 0) ,
254 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800255#ifdef FEATURE_WLAN_CH144
256 HDD5GHZCHAN(5720,144, 0) ,
257#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700258 HDD5GHZCHAN(5745,149, 0) ,
259 HDD5GHZCHAN(5765,153, 0) ,
260 HDD5GHZCHAN(5785,157, 0) ,
261 HDD5GHZCHAN(5805,161, 0) ,
262 HDD5GHZCHAN(5825,165, 0) ,
263};
264
265static struct ieee80211_rate g_mode_rates[] =
266{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530267 HDD_G_MODE_RATETAB(10, 0x1, 0),
268 HDD_G_MODE_RATETAB(20, 0x2, 0),
269 HDD_G_MODE_RATETAB(55, 0x4, 0),
270 HDD_G_MODE_RATETAB(110, 0x8, 0),
271 HDD_G_MODE_RATETAB(60, 0x10, 0),
272 HDD_G_MODE_RATETAB(90, 0x20, 0),
273 HDD_G_MODE_RATETAB(120, 0x40, 0),
274 HDD_G_MODE_RATETAB(180, 0x80, 0),
275 HDD_G_MODE_RATETAB(240, 0x100, 0),
276 HDD_G_MODE_RATETAB(360, 0x200, 0),
277 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700278 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530279};
Jeff Johnson295189b2012-06-20 16:38:30 -0700280
281static struct ieee80211_rate a_mode_rates[] =
282{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530283 HDD_G_MODE_RATETAB(60, 0x10, 0),
284 HDD_G_MODE_RATETAB(90, 0x20, 0),
285 HDD_G_MODE_RATETAB(120, 0x40, 0),
286 HDD_G_MODE_RATETAB(180, 0x80, 0),
287 HDD_G_MODE_RATETAB(240, 0x100, 0),
288 HDD_G_MODE_RATETAB(360, 0x200, 0),
289 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700290 HDD_G_MODE_RATETAB(540, 0x800, 0),
291};
292
293static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
294{
295 .channels = hdd_channels_2_4_GHZ,
296 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
297 .band = IEEE80211_BAND_2GHZ,
298 .bitrates = g_mode_rates,
299 .n_bitrates = g_mode_rates_size,
300 .ht_cap.ht_supported = 1,
301 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
302 | IEEE80211_HT_CAP_GRN_FLD
303 | IEEE80211_HT_CAP_DSSSCCK40
304 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
305 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
306 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
307 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
308 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
309 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
310};
311
Jeff Johnson295189b2012-06-20 16:38:30 -0700312static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
313{
314 .channels = hdd_social_channels_2_4_GHZ,
315 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
316 .band = IEEE80211_BAND_2GHZ,
317 .bitrates = g_mode_rates,
318 .n_bitrates = g_mode_rates_size,
319 .ht_cap.ht_supported = 1,
320 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
321 | IEEE80211_HT_CAP_GRN_FLD
322 | IEEE80211_HT_CAP_DSSSCCK40
323 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
324 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
325 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
326 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
327 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
328 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
329};
Jeff Johnson295189b2012-06-20 16:38:30 -0700330
331static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
332{
333 .channels = hdd_channels_5_GHZ,
334 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
335 .band = IEEE80211_BAND_5GHZ,
336 .bitrates = a_mode_rates,
337 .n_bitrates = a_mode_rates_size,
338 .ht_cap.ht_supported = 1,
339 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
340 | IEEE80211_HT_CAP_GRN_FLD
341 | IEEE80211_HT_CAP_DSSSCCK40
342 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
343 | IEEE80211_HT_CAP_SGI_40
344 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
345 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
346 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
347 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
348 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
349 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
350};
351
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530352/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700353 TX/RX direction for each kind of interface */
354static const struct ieee80211_txrx_stypes
355wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
356 [NL80211_IFTYPE_STATION] = {
357 .tx = 0xffff,
358 .rx = BIT(SIR_MAC_MGMT_ACTION) |
359 BIT(SIR_MAC_MGMT_PROBE_REQ),
360 },
361 [NL80211_IFTYPE_AP] = {
362 .tx = 0xffff,
363 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
364 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
365 BIT(SIR_MAC_MGMT_PROBE_REQ) |
366 BIT(SIR_MAC_MGMT_DISASSOC) |
367 BIT(SIR_MAC_MGMT_AUTH) |
368 BIT(SIR_MAC_MGMT_DEAUTH) |
369 BIT(SIR_MAC_MGMT_ACTION),
370 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700371 [NL80211_IFTYPE_ADHOC] = {
372 .tx = 0xffff,
373 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
374 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
375 BIT(SIR_MAC_MGMT_PROBE_REQ) |
376 BIT(SIR_MAC_MGMT_DISASSOC) |
377 BIT(SIR_MAC_MGMT_AUTH) |
378 BIT(SIR_MAC_MGMT_DEAUTH) |
379 BIT(SIR_MAC_MGMT_ACTION),
380 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700381 [NL80211_IFTYPE_P2P_CLIENT] = {
382 .tx = 0xffff,
383 .rx = BIT(SIR_MAC_MGMT_ACTION) |
384 BIT(SIR_MAC_MGMT_PROBE_REQ),
385 },
386 [NL80211_IFTYPE_P2P_GO] = {
387 /* This is also same as for SoftAP */
388 .tx = 0xffff,
389 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
390 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
391 BIT(SIR_MAC_MGMT_PROBE_REQ) |
392 BIT(SIR_MAC_MGMT_DISASSOC) |
393 BIT(SIR_MAC_MGMT_AUTH) |
394 BIT(SIR_MAC_MGMT_DEAUTH) |
395 BIT(SIR_MAC_MGMT_ACTION),
396 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700397};
398
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800399#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800400static const struct ieee80211_iface_limit
401wlan_hdd_iface_limit[] = {
402 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800403 /* max = 3 ; Our driver create two interfaces during driver init
404 * wlan0 and p2p0 interfaces. p2p0 is considered as station
405 * interface until a group is formed. In JB architecture, once the
406 * group is formed, interface type of p2p0 is changed to P2P GO or
407 * Client.
408 * When supplicant remove the group, it first issue a set interface
409 * cmd to change the mode back to Station. In JB this works fine as
410 * we advertize two station type interface during driver init.
411 * Some vendors create separate interface for P2P GO/Client,
412 * after group formation(Third one). But while group remove
413 * supplicant first tries to change the mode(3rd interface) to STATION
414 * But as we advertized only two sta type interfaces nl80211 was
415 * returning error for the third one which was leading to failure in
416 * delete interface. Ideally while removing the group, supplicant
417 * should not try to change the 3rd interface mode to Station type.
418 * Till we get a fix in wpa_supplicant, we advertize max STA
419 * interface type to 3
420 */
421 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800422 .types = BIT(NL80211_IFTYPE_STATION),
423 },
424 {
425 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700426 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800427 },
428 {
429 .max = 1,
430 .types = BIT(NL80211_IFTYPE_P2P_GO) |
431 BIT(NL80211_IFTYPE_P2P_CLIENT),
432 },
433};
434
435/* By default, only single channel concurrency is allowed */
436static struct ieee80211_iface_combination
437wlan_hdd_iface_combination = {
438 .limits = wlan_hdd_iface_limit,
439 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800440 /*
441 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
442 * and p2p0 interfaces during driver init
443 * Some vendors create separate interface for P2P operations.
444 * wlan0: STA interface
445 * p2p0: P2P Device interface, action frames goes
446 * through this interface.
447 * p2p-xx: P2P interface, After GO negotiation this interface is
448 * created for p2p operations(GO/CLIENT interface).
449 */
450 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800451 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
452 .beacon_int_infra_match = false,
453};
454#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800455
Jeff Johnson295189b2012-06-20 16:38:30 -0700456static struct cfg80211_ops wlan_hdd_cfg80211_ops;
457
458/* Data rate 100KBPS based on IE Index */
459struct index_data_rate_type
460{
461 v_U8_t beacon_rate_index;
462 v_U16_t supported_rate[4];
463};
464
465/* 11B, 11G Rate table include Basic rate and Extended rate
466 The IDX field is the rate index
467 The HI field is the rate when RSSI is strong or being ignored
468 (in this case we report actual rate)
469 The MID field is the rate when RSSI is moderate
470 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
471 The LO field is the rate when RSSI is low
472 (in this case we don't report rates, actual current rate used)
473 */
474static const struct
475{
476 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700477 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700478} supported_data_rate[] =
479{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700480/* IDX HI HM LM LO (RSSI-based index */
481 {2, { 10, 10, 10, 0}},
482 {4, { 20, 20, 10, 0}},
483 {11, { 55, 20, 10, 0}},
484 {12, { 60, 55, 20, 0}},
485 {18, { 90, 55, 20, 0}},
486 {22, {110, 55, 20, 0}},
487 {24, {120, 90, 60, 0}},
488 {36, {180, 120, 60, 0}},
489 {44, {220, 180, 60, 0}},
490 {48, {240, 180, 90, 0}},
491 {66, {330, 180, 90, 0}},
492 {72, {360, 240, 90, 0}},
493 {96, {480, 240, 120, 0}},
494 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700495};
496
497/* MCS Based rate table */
498static struct index_data_rate_type supported_mcs_rate[] =
499{
500/* MCS L20 L40 S20 S40 */
501 {0, {65, 135, 72, 150}},
502 {1, {130, 270, 144, 300}},
503 {2, {195, 405, 217, 450}},
504 {3, {260, 540, 289, 600}},
505 {4, {390, 810, 433, 900}},
506 {5, {520, 1080, 578, 1200}},
507 {6, {585, 1215, 650, 1350}},
508 {7, {650, 1350, 722, 1500}}
509};
510
Leo Chang6f8870f2013-03-26 18:11:36 -0700511#ifdef WLAN_FEATURE_11AC
512
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530513#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700514
515struct index_vht_data_rate_type
516{
517 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530518 v_U16_t supported_VHT80_rate[2];
519 v_U16_t supported_VHT40_rate[2];
520 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700521};
522
523typedef enum
524{
525 DATA_RATE_11AC_MAX_MCS_7,
526 DATA_RATE_11AC_MAX_MCS_8,
527 DATA_RATE_11AC_MAX_MCS_9,
528 DATA_RATE_11AC_MAX_MCS_NA
529} eDataRate11ACMaxMcs;
530
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530531/* SSID broadcast type */
532typedef enum eSSIDBcastType
533{
534 eBCAST_UNKNOWN = 0,
535 eBCAST_NORMAL = 1,
536 eBCAST_HIDDEN = 2,
537} tSSIDBcastType;
538
Leo Chang6f8870f2013-03-26 18:11:36 -0700539/* MCS Based VHT rate table */
540static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
541{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530542/* MCS L80 S80 L40 S40 L20 S40*/
543 {0, {293, 325}, {135, 150}, {65, 72}},
544 {1, {585, 650}, {270, 300}, {130, 144}},
545 {2, {878, 975}, {405, 450}, {195, 217}},
546 {3, {1170, 1300}, {540, 600}, {260, 289}},
547 {4, {1755, 1950}, {810, 900}, {390, 433}},
548 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
549 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
550 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
551 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
552 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700553};
554#endif /* WLAN_FEATURE_11AC */
555
c_hpothu79aab322014-07-14 21:11:01 +0530556/*array index points to MCS and array value points respective rssi*/
557static int rssiMcsTbl[][10] =
558{
559/*MCS 0 1 2 3 4 5 6 7 8 9*/
560 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
561 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
562 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
563};
564
Jeff Johnson295189b2012-06-20 16:38:30 -0700565extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530566#ifdef FEATURE_WLAN_SCAN_PNO
567static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
568#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700569
Leo Chang9056f462013-08-01 19:21:11 -0700570#ifdef WLAN_NL80211_TESTMODE
571enum wlan_hdd_tm_attr
572{
573 WLAN_HDD_TM_ATTR_INVALID = 0,
574 WLAN_HDD_TM_ATTR_CMD = 1,
575 WLAN_HDD_TM_ATTR_DATA = 2,
576 WLAN_HDD_TM_ATTR_TYPE = 3,
577 /* keep last */
578 WLAN_HDD_TM_ATTR_AFTER_LAST,
579 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
580};
581
582enum wlan_hdd_tm_cmd
583{
584 WLAN_HDD_TM_CMD_WLAN_HB = 1,
585};
586
587#define WLAN_HDD_TM_DATA_MAX_LEN 5000
588
589static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
590{
591 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
592 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
593 .len = WLAN_HDD_TM_DATA_MAX_LEN },
594};
595#endif /* WLAN_NL80211_TESTMODE */
596
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800597#ifdef FEATURE_WLAN_CH_AVOID
598/*
599 * FUNCTION: wlan_hdd_send_avoid_freq_event
600 * This is called when wlan driver needs to send vendor specific
601 * avoid frequency range event to userspace
602 */
603int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
604 tHddAvoidFreqList *pAvoidFreqList)
605{
606 struct sk_buff *vendor_event;
607
608 ENTER();
609
610 if (!pHddCtx)
611 {
612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
613 "%s: HDD context is null", __func__);
614 return -1;
615 }
616
617 if (!pAvoidFreqList)
618 {
619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
620 "%s: pAvoidFreqList is null", __func__);
621 return -1;
622 }
623
624 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530625#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
626 NULL,
627#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800628 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530629 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800630 GFP_KERNEL);
631 if (!vendor_event)
632 {
633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
634 "%s: cfg80211_vendor_event_alloc failed", __func__);
635 return -1;
636 }
637
638 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
639 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
640
641 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
642
643 EXIT();
644 return 0;
645}
646#endif /* FEATURE_WLAN_CH_AVOID */
647
Srinivas Dasari030bad32015-02-18 23:23:54 +0530648/*
649 * FUNCTION: __wlan_hdd_cfg80211_nan_request
650 * This is called when wlan driver needs to send vendor specific
651 * nan request event.
652 */
653static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
654 struct wireless_dev *wdev,
655 const void *data, int data_len)
656{
657 tNanRequestReq nan_req;
658 VOS_STATUS status;
659 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530660 struct net_device *dev = wdev->netdev;
661 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
662 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530663 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
664
665 if (0 == data_len)
666 {
667 hddLog(VOS_TRACE_LEVEL_ERROR,
668 FL("NAN - Invalid Request, length = 0"));
669 return ret_val;
670 }
671
672 if (NULL == data)
673 {
674 hddLog(VOS_TRACE_LEVEL_ERROR,
675 FL("NAN - Invalid Request, data is NULL"));
676 return ret_val;
677 }
678
679 status = wlan_hdd_validate_context(pHddCtx);
680 if (0 != status)
681 {
682 hddLog(VOS_TRACE_LEVEL_ERROR,
683 FL("HDD context is not valid"));
684 return -EINVAL;
685 }
686
687 hddLog(LOG1, FL("Received NAN command"));
688 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
689 (tANI_U8 *)data, data_len);
690
691 /* check the NAN Capability */
692 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
693 {
694 hddLog(VOS_TRACE_LEVEL_ERROR,
695 FL("NAN is not supported by Firmware"));
696 return -EINVAL;
697 }
698
699 nan_req.request_data_len = data_len;
700 nan_req.request_data = data;
701
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530702 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530703 if (VOS_STATUS_SUCCESS == status)
704 {
705 ret_val = 0;
706 }
707 return ret_val;
708}
709
710/*
711 * FUNCTION: wlan_hdd_cfg80211_nan_request
712 * Wrapper to protect the nan vendor command from ssr
713 */
714static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
715 struct wireless_dev *wdev,
716 const void *data, int data_len)
717{
718 int ret;
719
720 vos_ssr_protect(__func__);
721 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
722 vos_ssr_unprotect(__func__);
723
724 return ret;
725}
726
727/*
728 * FUNCTION: wlan_hdd_cfg80211_nan_callback
729 * This is a callback function and it gets called
730 * when we need to report nan response event to
731 * upper layers.
732 */
733static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
734{
735 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
736 struct sk_buff *vendor_event;
737 int status;
738 tSirNanEvent *data;
739
740 ENTER();
741 if (NULL == msg)
742 {
743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
744 FL(" msg received here is null"));
745 return;
746 }
747 data = msg;
748
749 status = wlan_hdd_validate_context(pHddCtx);
750
751 if (0 != status)
752 {
753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
754 FL("HDD context is not valid"));
755 return;
756 }
757
758 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530759#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
760 NULL,
761#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530762 data->event_data_len +
763 NLMSG_HDRLEN,
764 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
765 GFP_KERNEL);
766
767 if (!vendor_event)
768 {
769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
770 FL("cfg80211_vendor_event_alloc failed"));
771 return;
772 }
773 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
774 data->event_data_len, data->event_data))
775 {
776 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
777 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
778 kfree_skb(vendor_event);
779 return;
780 }
781 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
782 EXIT();
783}
784
785/*
786 * FUNCTION: wlan_hdd_cfg80211_nan_init
787 * This function is called to register the callback to sme layer
788 */
789inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
790{
791 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
792}
793
794
Sunil Duttc69bccb2014-05-26 21:30:20 +0530795#ifdef WLAN_FEATURE_LINK_LAYER_STATS
796
797static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
798 struct sk_buff *vendor_event)
799{
800 if (nla_put_u8(vendor_event,
801 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
802 stats->rate.preamble) ||
803 nla_put_u8(vendor_event,
804 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
805 stats->rate.nss) ||
806 nla_put_u8(vendor_event,
807 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
808 stats->rate.bw) ||
809 nla_put_u8(vendor_event,
810 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
811 stats->rate.rateMcsIdx) ||
812 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
813 stats->rate.bitrate ) ||
814 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
815 stats->txMpdu ) ||
816 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
817 stats->rxMpdu ) ||
818 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
819 stats->mpduLost ) ||
820 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
821 stats->retries) ||
822 nla_put_u32(vendor_event,
823 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
824 stats->retriesShort ) ||
825 nla_put_u32(vendor_event,
826 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
827 stats->retriesLong))
828 {
829 hddLog(VOS_TRACE_LEVEL_ERROR,
830 FL("QCA_WLAN_VENDOR_ATTR put fail"));
831 return FALSE;
832 }
833 return TRUE;
834}
835
836static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
837 struct sk_buff *vendor_event)
838{
839 u32 i = 0;
840 struct nlattr *rateInfo;
841 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
842 stats->type) ||
843 nla_put(vendor_event,
844 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
845 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
846 nla_put_u32(vendor_event,
847 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
848 stats->capabilities) ||
849 nla_put_u32(vendor_event,
850 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
851 stats->numRate))
852 {
853 hddLog(VOS_TRACE_LEVEL_ERROR,
854 FL("QCA_WLAN_VENDOR_ATTR put fail"));
855 goto error;
856 }
857
858 rateInfo = nla_nest_start(vendor_event,
859 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530860 if(!rateInfo)
861 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530862 for (i = 0; i < stats->numRate; i++)
863 {
864 struct nlattr *rates;
865 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
866 stats->rateStats +
867 (i * sizeof(tSirWifiRateStat)));
868 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530869 if(!rates)
870 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530871
872 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
873 {
874 hddLog(VOS_TRACE_LEVEL_ERROR,
875 FL("QCA_WLAN_VENDOR_ATTR put fail"));
876 return FALSE;
877 }
878 nla_nest_end(vendor_event, rates);
879 }
880 nla_nest_end(vendor_event, rateInfo);
881
882 return TRUE;
883error:
884 return FALSE;
885}
886
887static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
888 struct sk_buff *vendor_event)
889{
890 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
891 stats->ac ) ||
892 nla_put_u32(vendor_event,
893 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
894 stats->txMpdu ) ||
895 nla_put_u32(vendor_event,
896 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
897 stats->rxMpdu ) ||
898 nla_put_u32(vendor_event,
899 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
900 stats->txMcast ) ||
901 nla_put_u32(vendor_event,
902 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
903 stats->rxMcast ) ||
904 nla_put_u32(vendor_event,
905 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
906 stats->rxAmpdu ) ||
907 nla_put_u32(vendor_event,
908 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
909 stats->txAmpdu ) ||
910 nla_put_u32(vendor_event,
911 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
912 stats->mpduLost )||
913 nla_put_u32(vendor_event,
914 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
915 stats->retries ) ||
916 nla_put_u32(vendor_event,
917 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
918 stats->retriesShort ) ||
919 nla_put_u32(vendor_event,
920 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
921 stats->retriesLong ) ||
922 nla_put_u32(vendor_event,
923 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
924 stats->contentionTimeMin ) ||
925 nla_put_u32(vendor_event,
926 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
927 stats->contentionTimeMax ) ||
928 nla_put_u32(vendor_event,
929 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
930 stats->contentionTimeAvg ) ||
931 nla_put_u32(vendor_event,
932 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
933 stats->contentionNumSamples ))
934 {
935 hddLog(VOS_TRACE_LEVEL_ERROR,
936 FL("QCA_WLAN_VENDOR_ATTR put fail") );
937 return FALSE;
938 }
939 return TRUE;
940}
941
942static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
943 struct sk_buff *vendor_event)
944{
Dino Myclec8f3f332014-07-21 16:48:27 +0530945 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530946 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
947 nla_put(vendor_event,
948 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
949 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
950 nla_put_u32(vendor_event,
951 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
952 stats->state ) ||
953 nla_put_u32(vendor_event,
954 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
955 stats->roaming ) ||
956 nla_put_u32(vendor_event,
957 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
958 stats->capabilities ) ||
959 nla_put(vendor_event,
960 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
961 strlen(stats->ssid), stats->ssid) ||
962 nla_put(vendor_event,
963 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
964 WNI_CFG_BSSID_LEN, stats->bssid) ||
965 nla_put(vendor_event,
966 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
967 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
968 nla_put(vendor_event,
969 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
970 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
971 )
972 {
973 hddLog(VOS_TRACE_LEVEL_ERROR,
974 FL("QCA_WLAN_VENDOR_ATTR put fail") );
975 return FALSE;
976 }
977 return TRUE;
978}
979
Dino Mycle3b9536d2014-07-09 22:05:24 +0530980static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
981 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530982 struct sk_buff *vendor_event)
983{
984 int i = 0;
985 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530986 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
987 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530988 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530989
Sunil Duttc69bccb2014-05-26 21:30:20 +0530990 if (FALSE == put_wifi_interface_info(
991 &pWifiIfaceStat->info,
992 vendor_event))
993 {
994 hddLog(VOS_TRACE_LEVEL_ERROR,
995 FL("QCA_WLAN_VENDOR_ATTR put fail") );
996 return FALSE;
997
998 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530999 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
1000 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
1001 if (NULL == pWifiIfaceStatTL)
1002 {
1003 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
1004 return FALSE;
1005 }
1006
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301007 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
1008 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1009 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1010 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1011
1012 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1013 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1014 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1015 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301016
1017 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1018 {
1019 if (VOS_STATUS_SUCCESS ==
1020 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1021 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1022 {
1023 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1024 * obtained from TL structure
1025 */
1026
1027 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1028 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301029 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1030
Srinivas Dasari98947432014-11-07 19:41:24 +05301031 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1032 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1033 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1034 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1035 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1036 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1037 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1038 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301039
Srinivas Dasari98947432014-11-07 19:41:24 +05301040 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1041 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1042 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1043 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1044 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1045 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1046 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1047 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301048
Srinivas Dasari98947432014-11-07 19:41:24 +05301049 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1050 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1051 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1052 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1053 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1054 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1055 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1056 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301057 }
1058 else
1059 {
1060 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1061 }
1062
Dino Mycle3b9536d2014-07-09 22:05:24 +05301063 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1064 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1065 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1066 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1067 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1068 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1069 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1070 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1071 }
1072 else
1073 {
1074 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1075 }
1076
1077
Sunil Duttc69bccb2014-05-26 21:30:20 +05301078
1079 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301080 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1081 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1082 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301083 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1084 pWifiIfaceStat->beaconRx) ||
1085 nla_put_u32(vendor_event,
1086 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1087 pWifiIfaceStat->mgmtRx) ||
1088 nla_put_u32(vendor_event,
1089 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1090 pWifiIfaceStat->mgmtActionRx) ||
1091 nla_put_u32(vendor_event,
1092 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1093 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301094 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301095 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1096 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301097 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301098 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1099 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301100 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301101 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1102 pWifiIfaceStat->rssiAck))
1103 {
1104 hddLog(VOS_TRACE_LEVEL_ERROR,
1105 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301106 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301107 return FALSE;
1108 }
1109
1110 wmmInfo = nla_nest_start(vendor_event,
1111 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301112 if(!wmmInfo)
1113 {
1114 vos_mem_free(pWifiIfaceStatTL);
1115 return FALSE;
1116 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301117 for (i = 0; i < WIFI_AC_MAX; i++)
1118 {
1119 struct nlattr *wmmStats;
1120 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301121 if(!wmmStats)
1122 {
1123 vos_mem_free(pWifiIfaceStatTL);
1124 return FALSE;
1125 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301126 if (FALSE == put_wifi_wmm_ac_stat(
1127 &pWifiIfaceStat->AccessclassStats[i],
1128 vendor_event))
1129 {
1130 hddLog(VOS_TRACE_LEVEL_ERROR,
1131 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301132 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301133 return FALSE;
1134 }
1135
1136 nla_nest_end(vendor_event, wmmStats);
1137 }
1138 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301139 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301140 return TRUE;
1141}
1142
1143static tSirWifiInterfaceMode
1144 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1145{
1146 switch (deviceMode)
1147 {
1148 case WLAN_HDD_INFRA_STATION:
1149 return WIFI_INTERFACE_STA;
1150 case WLAN_HDD_SOFTAP:
1151 return WIFI_INTERFACE_SOFTAP;
1152 case WLAN_HDD_P2P_CLIENT:
1153 return WIFI_INTERFACE_P2P_CLIENT;
1154 case WLAN_HDD_P2P_GO:
1155 return WIFI_INTERFACE_P2P_GO;
1156 case WLAN_HDD_IBSS:
1157 return WIFI_INTERFACE_IBSS;
1158 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301159 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301160 }
1161}
1162
1163static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1164 tpSirWifiInterfaceInfo pInfo)
1165{
1166 v_U8_t *staMac = NULL;
1167 hdd_station_ctx_t *pHddStaCtx;
1168 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1169 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1170
1171 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1172
1173 vos_mem_copy(pInfo->macAddr,
1174 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1175
1176 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1177 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1178 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1179 {
1180 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1181 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1182 {
1183 pInfo->state = WIFI_DISCONNECTED;
1184 }
1185 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1186 {
1187 hddLog(VOS_TRACE_LEVEL_ERROR,
1188 "%s: Session ID %d, Connection is in progress", __func__,
1189 pAdapter->sessionId);
1190 pInfo->state = WIFI_ASSOCIATING;
1191 }
1192 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1193 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1194 {
1195 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1196 hddLog(VOS_TRACE_LEVEL_ERROR,
1197 "%s: client " MAC_ADDRESS_STR
1198 " is in the middle of WPS/EAPOL exchange.", __func__,
1199 MAC_ADDR_ARRAY(staMac));
1200 pInfo->state = WIFI_AUTHENTICATING;
1201 }
1202 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1203 {
1204 pInfo->state = WIFI_ASSOCIATED;
1205 vos_mem_copy(pInfo->bssid,
1206 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1207 vos_mem_copy(pInfo->ssid,
1208 pHddStaCtx->conn_info.SSID.SSID.ssId,
1209 pHddStaCtx->conn_info.SSID.SSID.length);
1210 //NULL Terminate the string.
1211 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1212 }
1213 }
1214 vos_mem_copy(pInfo->countryStr,
1215 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1216
1217 vos_mem_copy(pInfo->apCountryStr,
1218 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1219
1220 return TRUE;
1221}
1222
1223/*
1224 * hdd_link_layer_process_peer_stats () - This function is called after
1225 * receiving Link Layer Peer statistics from FW.This function converts
1226 * the firmware data to the NL data and sends the same to the kernel/upper
1227 * layers.
1228 */
1229static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1230 v_VOID_t *pData)
1231{
1232 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301233 tpSirWifiPeerStat pWifiPeerStat;
1234 tpSirWifiPeerInfo pWifiPeerInfo;
1235 struct nlattr *peerInfo;
1236 struct sk_buff *vendor_event;
1237 int status, i;
1238
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301239 ENTER();
1240
Sunil Duttc69bccb2014-05-26 21:30:20 +05301241 status = wlan_hdd_validate_context(pHddCtx);
1242 if (0 != status)
1243 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301244 return;
1245 }
1246
1247 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1248
1249 hddLog(VOS_TRACE_LEVEL_INFO,
1250 "LL_STATS_PEER_ALL : numPeers %u",
1251 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301252 /*
1253 * Allocate a size of 4096 for the peer stats comprising
1254 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1255 * sizeof (tSirWifiRateStat).Each field is put with an
1256 * NL attribute.The size of 4096 is considered assuming
1257 * that number of rates shall not exceed beyond 50 with
1258 * the sizeof (tSirWifiRateStat) being 32.
1259 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301260 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1261 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301262 if (!vendor_event)
1263 {
1264 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301265 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301266 __func__);
1267 return;
1268 }
1269 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301270 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1271 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1272 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301273 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1274 pWifiPeerStat->numPeers))
1275 {
1276 hddLog(VOS_TRACE_LEVEL_ERROR,
1277 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1278 kfree_skb(vendor_event);
1279 return;
1280 }
1281
1282 peerInfo = nla_nest_start(vendor_event,
1283 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301284 if(!peerInfo)
1285 {
1286 hddLog(VOS_TRACE_LEVEL_ERROR,
1287 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1288 __func__);
1289 kfree_skb(vendor_event);
1290 return;
1291 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301292
1293 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1294 pWifiPeerStat->peerInfo);
1295
1296 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1297 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301298 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301299 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301300
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301301 if(!peers)
1302 {
1303 hddLog(VOS_TRACE_LEVEL_ERROR,
1304 "%s: peer stats put fail",
1305 __func__);
1306 kfree_skb(vendor_event);
1307 return;
1308 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301309 if (FALSE == put_wifi_peer_info(
1310 pWifiPeerInfo, vendor_event))
1311 {
1312 hddLog(VOS_TRACE_LEVEL_ERROR,
1313 "%s: put_wifi_peer_info put fail", __func__);
1314 kfree_skb(vendor_event);
1315 return;
1316 }
1317
1318 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1319 pWifiPeerStat->peerInfo +
1320 (i * sizeof(tSirWifiPeerInfo)) +
1321 (numRate * sizeof (tSirWifiRateStat)));
1322 nla_nest_end(vendor_event, peers);
1323 }
1324 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301325 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301326 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301327}
1328
1329/*
1330 * hdd_link_layer_process_iface_stats () - This function is called after
1331 * receiving Link Layer Interface statistics from FW.This function converts
1332 * the firmware data to the NL data and sends the same to the kernel/upper
1333 * layers.
1334 */
1335static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1336 v_VOID_t *pData)
1337{
1338 tpSirWifiIfaceStat pWifiIfaceStat;
1339 struct sk_buff *vendor_event;
1340 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1341 int status;
1342
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301343 ENTER();
1344
Sunil Duttc69bccb2014-05-26 21:30:20 +05301345 status = wlan_hdd_validate_context(pHddCtx);
1346 if (0 != status)
1347 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301348 return;
1349 }
1350 /*
1351 * Allocate a size of 4096 for the interface stats comprising
1352 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1353 * assuming that all these fit with in the limit.Please take
1354 * a call on the limit based on the data requirements on
1355 * interface statistics.
1356 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301357 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1358 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301359 if (!vendor_event)
1360 {
1361 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301362 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301363 return;
1364 }
1365
1366 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1367
Dino Mycle3b9536d2014-07-09 22:05:24 +05301368
1369 if (FALSE == hdd_get_interface_info( pAdapter,
1370 &pWifiIfaceStat->info))
1371 {
1372 hddLog(VOS_TRACE_LEVEL_ERROR,
1373 FL("hdd_get_interface_info get fail") );
1374 kfree_skb(vendor_event);
1375 return;
1376 }
1377
1378 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1379 vendor_event))
1380 {
1381 hddLog(VOS_TRACE_LEVEL_ERROR,
1382 FL("put_wifi_iface_stats fail") );
1383 kfree_skb(vendor_event);
1384 return;
1385 }
1386
Sunil Duttc69bccb2014-05-26 21:30:20 +05301387 hddLog(VOS_TRACE_LEVEL_INFO,
1388 "WMI_LINK_STATS_IFACE Data");
1389
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301390 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301391
1392 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301393}
1394
1395/*
1396 * hdd_link_layer_process_radio_stats () - This function is called after
1397 * receiving Link Layer Radio statistics from FW.This function converts
1398 * the firmware data to the NL data and sends the same to the kernel/upper
1399 * layers.
1400 */
1401static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1402 v_VOID_t *pData)
1403{
1404 int status, i;
1405 tpSirWifiRadioStat pWifiRadioStat;
1406 tpSirWifiChannelStats pWifiChannelStats;
1407 struct sk_buff *vendor_event;
1408 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1409 struct nlattr *chList;
1410
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301411 ENTER();
1412
Sunil Duttc69bccb2014-05-26 21:30:20 +05301413 status = wlan_hdd_validate_context(pHddCtx);
1414 if (0 != status)
1415 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301416 return;
1417 }
1418 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1419
1420 hddLog(VOS_TRACE_LEVEL_INFO,
1421 "LL_STATS_RADIO"
1422 " radio is %d onTime is %u "
1423 " txTime is %u rxTime is %u "
1424 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301425 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301426 " onTimePnoScan is %u onTimeHs20 is %u "
1427 " numChannels is %u",
1428 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1429 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1430 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301431 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301432 pWifiRadioStat->onTimeRoamScan,
1433 pWifiRadioStat->onTimePnoScan,
1434 pWifiRadioStat->onTimeHs20,
1435 pWifiRadioStat->numChannels);
1436 /*
1437 * Allocate a size of 4096 for the Radio stats comprising
1438 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1439 * (tSirWifiChannelStats).Each channel data is put with an
1440 * NL attribute.The size of 4096 is considered assuming that
1441 * number of channels shall not exceed beyond 60 with the
1442 * sizeof (tSirWifiChannelStats) being 24 bytes.
1443 */
1444
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301445 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1446 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301447 if (!vendor_event)
1448 {
1449 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301450 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301451 return;
1452 }
1453
1454 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301455 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1456 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1457 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301458 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1459 pWifiRadioStat->radio) ||
1460 nla_put_u32(vendor_event,
1461 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1462 pWifiRadioStat->onTime) ||
1463 nla_put_u32(vendor_event,
1464 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1465 pWifiRadioStat->txTime) ||
1466 nla_put_u32(vendor_event,
1467 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1468 pWifiRadioStat->rxTime) ||
1469 nla_put_u32(vendor_event,
1470 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1471 pWifiRadioStat->onTimeScan) ||
1472 nla_put_u32(vendor_event,
1473 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1474 pWifiRadioStat->onTimeNbd) ||
1475 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301476 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1477 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301478 nla_put_u32(vendor_event,
1479 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1480 pWifiRadioStat->onTimeRoamScan) ||
1481 nla_put_u32(vendor_event,
1482 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1483 pWifiRadioStat->onTimePnoScan) ||
1484 nla_put_u32(vendor_event,
1485 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1486 pWifiRadioStat->onTimeHs20) ||
1487 nla_put_u32(vendor_event,
1488 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1489 pWifiRadioStat->numChannels))
1490 {
1491 hddLog(VOS_TRACE_LEVEL_ERROR,
1492 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1493 kfree_skb(vendor_event);
1494 return ;
1495 }
1496
1497 chList = nla_nest_start(vendor_event,
1498 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301499 if(!chList)
1500 {
1501 hddLog(VOS_TRACE_LEVEL_ERROR,
1502 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1503 __func__);
1504 kfree_skb(vendor_event);
1505 return;
1506 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301507 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1508 {
1509 struct nlattr *chInfo;
1510
1511 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1512 pWifiRadioStat->channels +
1513 (i * sizeof(tSirWifiChannelStats)));
1514
Sunil Duttc69bccb2014-05-26 21:30:20 +05301515 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301516 if(!chInfo)
1517 {
1518 hddLog(VOS_TRACE_LEVEL_ERROR,
1519 "%s: failed to put chInfo",
1520 __func__);
1521 kfree_skb(vendor_event);
1522 return;
1523 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301524
1525 if (nla_put_u32(vendor_event,
1526 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1527 pWifiChannelStats->channel.width) ||
1528 nla_put_u32(vendor_event,
1529 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1530 pWifiChannelStats->channel.centerFreq) ||
1531 nla_put_u32(vendor_event,
1532 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1533 pWifiChannelStats->channel.centerFreq0) ||
1534 nla_put_u32(vendor_event,
1535 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1536 pWifiChannelStats->channel.centerFreq1) ||
1537 nla_put_u32(vendor_event,
1538 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1539 pWifiChannelStats->onTime) ||
1540 nla_put_u32(vendor_event,
1541 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1542 pWifiChannelStats->ccaBusyTime))
1543 {
1544 hddLog(VOS_TRACE_LEVEL_ERROR,
1545 FL("cfg80211_vendor_event_alloc failed") );
1546 kfree_skb(vendor_event);
1547 return ;
1548 }
1549 nla_nest_end(vendor_event, chInfo);
1550 }
1551 nla_nest_end(vendor_event, chList);
1552
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301553 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301554
1555 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301556 return;
1557}
1558
1559/*
1560 * hdd_link_layer_stats_ind_callback () - This function is called after
1561 * receiving Link Layer indications from FW.This callback converts the firmware
1562 * data to the NL data and send the same to the kernel/upper layers.
1563 */
1564static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1565 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301566 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301567{
Dino Mycled3d50022014-07-07 12:58:25 +05301568 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1569 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301570 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301571 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301572 int status;
1573
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301574 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301575
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301576 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301577 if (0 != status)
1578 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301579 return;
1580 }
1581
Dino Mycled3d50022014-07-07 12:58:25 +05301582 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1583 if (NULL == pAdapter)
1584 {
1585 hddLog(VOS_TRACE_LEVEL_ERROR,
1586 FL(" MAC address %pM does not exist with host"),
1587 macAddr);
1588 return;
1589 }
1590
Sunil Duttc69bccb2014-05-26 21:30:20 +05301591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301592 "%s: Interface: %s LLStats indType: %d", __func__,
1593 pAdapter->dev->name, indType);
1594
Sunil Duttc69bccb2014-05-26 21:30:20 +05301595 switch (indType)
1596 {
1597 case SIR_HAL_LL_STATS_RESULTS_RSP:
1598 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301599 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301600 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
1601 "respId = %u, moreResultToFollow = %u",
1602 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
1603 macAddr, linkLayerStatsResults->respId,
1604 linkLayerStatsResults->moreResultToFollow);
1605
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301606 spin_lock(&hdd_context_lock);
1607 context = &pHddCtx->ll_stats_context;
1608 /* validate response received from target */
1609 if ((context->request_id != linkLayerStatsResults->respId) ||
1610 !(context->request_bitmap & linkLayerStatsResults->paramId))
1611 {
1612 spin_unlock(&hdd_context_lock);
1613 hddLog(LOGE,
1614 FL("Error : Request id %d response id %d request bitmap 0x%x"
1615 "response bitmap 0x%x"),
1616 context->request_id, linkLayerStatsResults->respId,
1617 context->request_bitmap, linkLayerStatsResults->paramId);
1618 return;
1619 }
1620 spin_unlock(&hdd_context_lock);
1621
Sunil Duttc69bccb2014-05-26 21:30:20 +05301622 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1623 {
1624 hdd_link_layer_process_radio_stats(pAdapter,
1625 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301626 spin_lock(&hdd_context_lock);
1627 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1628 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301629 }
1630 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1631 {
1632 hdd_link_layer_process_iface_stats(pAdapter,
1633 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301634 spin_lock(&hdd_context_lock);
1635 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1636 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301637 }
1638 else if ( linkLayerStatsResults->paramId &
1639 WMI_LINK_STATS_ALL_PEER )
1640 {
1641 hdd_link_layer_process_peer_stats(pAdapter,
1642 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301643 spin_lock(&hdd_context_lock);
1644 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1645 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301646 } /* WMI_LINK_STATS_ALL_PEER */
1647 else
1648 {
1649 hddLog(VOS_TRACE_LEVEL_ERROR,
1650 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1651 }
1652
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301653 spin_lock(&hdd_context_lock);
1654 /* complete response event if all requests are completed */
1655 if (0 == context->request_bitmap)
1656 complete(&context->response_event);
1657 spin_unlock(&hdd_context_lock);
1658
Sunil Duttc69bccb2014-05-26 21:30:20 +05301659 break;
1660 }
1661 default:
1662 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1663 break;
1664 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301665
1666 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301667 return;
1668}
1669
1670const struct
1671nla_policy
1672qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1673{
1674 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1675 { .type = NLA_U32 },
1676 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1677 { .type = NLA_U32 },
1678};
1679
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301680static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1681 struct wireless_dev *wdev,
1682 const void *data,
1683 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301684{
1685 int status;
1686 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301687 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301688 struct net_device *dev = wdev->netdev;
1689 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1690 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1691
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301692 ENTER();
1693
Sunil Duttc69bccb2014-05-26 21:30:20 +05301694 status = wlan_hdd_validate_context(pHddCtx);
1695 if (0 != status)
1696 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301697 return -EINVAL;
1698 }
1699
1700 if (NULL == pAdapter)
1701 {
1702 hddLog(VOS_TRACE_LEVEL_ERROR,
1703 FL("HDD adapter is Null"));
1704 return -ENODEV;
1705 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301706 /* check the LLStats Capability */
1707 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1708 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1709 {
1710 hddLog(VOS_TRACE_LEVEL_ERROR,
1711 FL("Link Layer Statistics not supported by Firmware"));
1712 return -EINVAL;
1713 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301714
1715 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1716 (struct nlattr *)data,
1717 data_len, qca_wlan_vendor_ll_set_policy))
1718 {
1719 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1720 return -EINVAL;
1721 }
1722 if (!tb_vendor
1723 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1724 {
1725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1726 return -EINVAL;
1727 }
1728 if (!tb_vendor[
1729 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1730 {
1731 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1732 return -EINVAL;
1733 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301734 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301735 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301736
Dino Mycledf0a5d92014-07-04 09:41:55 +05301737 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301738 nla_get_u32(
1739 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1740
Dino Mycledf0a5d92014-07-04 09:41:55 +05301741 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301742 nla_get_u32(
1743 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1744
Dino Mycled3d50022014-07-07 12:58:25 +05301745 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1746 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301747
1748
1749 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301750 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
1751 "Statistics Gathering = %d ",
1752 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
1753 linkLayerStatsSetReq.mpduSizeThreshold,
1754 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301755
1756 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1757 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301758 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301759 {
1760 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1761 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301762 return -EINVAL;
1763
1764 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301765
Sunil Duttc69bccb2014-05-26 21:30:20 +05301766 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301767 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301768 {
1769 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1770 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301771 return -EINVAL;
1772 }
1773
1774 pAdapter->isLinkLayerStatsSet = 1;
1775
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301776 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301777 return 0;
1778}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301779static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1780 struct wireless_dev *wdev,
1781 const void *data,
1782 int data_len)
1783{
1784 int ret = 0;
1785
1786 vos_ssr_protect(__func__);
1787 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1788 vos_ssr_unprotect(__func__);
1789
1790 return ret;
1791}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301792
1793const struct
1794nla_policy
1795qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1796{
1797 /* Unsigned 32bit value provided by the caller issuing the GET stats
1798 * command. When reporting
1799 * the stats results, the driver uses the same value to indicate
1800 * which GET request the results
1801 * correspond to.
1802 */
1803 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1804
1805 /* Unsigned 32bit value . bit mask to identify what statistics are
1806 requested for retrieval */
1807 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1808};
1809
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301810static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1811 struct wireless_dev *wdev,
1812 const void *data,
1813 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301814{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301815 unsigned long rc;
1816 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301817 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1818 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301819 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301820 struct net_device *dev = wdev->netdev;
1821 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301822 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301823 int status;
1824
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301825 ENTER();
1826
Sunil Duttc69bccb2014-05-26 21:30:20 +05301827 status = wlan_hdd_validate_context(pHddCtx);
1828 if (0 != status)
1829 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301830 return -EINVAL ;
1831 }
1832
1833 if (NULL == pAdapter)
1834 {
1835 hddLog(VOS_TRACE_LEVEL_FATAL,
1836 "%s: HDD adapter is Null", __func__);
1837 return -ENODEV;
1838 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05301839
1840 if (pHddStaCtx == NULL)
1841 {
1842 hddLog(VOS_TRACE_LEVEL_FATAL,
1843 "%s: HddStaCtx is Null", __func__);
1844 return -ENODEV;
1845 }
1846
Dino Mycledf0a5d92014-07-04 09:41:55 +05301847 /* check the LLStats Capability */
1848 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1849 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1850 {
1851 hddLog(VOS_TRACE_LEVEL_ERROR,
1852 FL("Link Layer Statistics not supported by Firmware"));
1853 return -EINVAL;
1854 }
1855
Sunil Duttc69bccb2014-05-26 21:30:20 +05301856
1857 if (!pAdapter->isLinkLayerStatsSet)
1858 {
Sushant Kaushikdc3184b2015-10-09 12:00:21 +05301859 hddLog(VOS_TRACE_LEVEL_ERROR,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301860 "%s: isLinkLayerStatsSet : %d",
1861 __func__, pAdapter->isLinkLayerStatsSet);
1862 return -EINVAL;
1863 }
1864
Mukul Sharma10313ba2015-07-29 19:14:39 +05301865 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
1866 {
1867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1868 "%s: Roaming in progress, so unable to proceed this request", __func__);
1869 return -EBUSY;
1870 }
1871
Sunil Duttc69bccb2014-05-26 21:30:20 +05301872 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1873 (struct nlattr *)data,
1874 data_len, qca_wlan_vendor_ll_get_policy))
1875 {
1876 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1877 return -EINVAL;
1878 }
1879
1880 if (!tb_vendor
1881 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1882 {
1883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1884 return -EINVAL;
1885 }
1886
1887 if (!tb_vendor
1888 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1889 {
1890 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1891 return -EINVAL;
1892 }
1893
Sunil Duttc69bccb2014-05-26 21:30:20 +05301894
Dino Mycledf0a5d92014-07-04 09:41:55 +05301895 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301896 nla_get_u32( tb_vendor[
1897 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301898 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301899 nla_get_u32( tb_vendor[
1900 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1901
Dino Mycled3d50022014-07-07 12:58:25 +05301902 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1903 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301904
1905 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301906 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
1907 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301908 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301909
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301910 spin_lock(&hdd_context_lock);
1911 context = &pHddCtx->ll_stats_context;
1912 context->request_id = linkLayerStatsGetReq.reqId;
1913 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
1914 INIT_COMPLETION(context->response_event);
1915 spin_unlock(&hdd_context_lock);
1916
Sunil Duttc69bccb2014-05-26 21:30:20 +05301917 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301918 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301919 {
1920 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1921 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301922 return -EINVAL;
1923 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301924
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301925 rc = wait_for_completion_timeout(&context->response_event,
1926 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
1927 if (!rc)
1928 {
1929 hddLog(LOGE,
1930 FL("Target response timed out request id %d request bitmap 0x%x"),
1931 context->request_id, context->request_bitmap);
1932 return -ETIMEDOUT;
1933 }
1934
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301935 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301936 return 0;
1937}
1938
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301939static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1940 struct wireless_dev *wdev,
1941 const void *data,
1942 int data_len)
1943{
1944 int ret = 0;
1945
1946 vos_ssr_protect(__func__);
1947 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1948 vos_ssr_unprotect(__func__);
1949
1950 return ret;
1951}
1952
Sunil Duttc69bccb2014-05-26 21:30:20 +05301953const struct
1954nla_policy
1955qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1956{
1957 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1958 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1959 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1960 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1961};
1962
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301963static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1964 struct wireless_dev *wdev,
1965 const void *data,
1966 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301967{
1968 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1969 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301970 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301971 struct net_device *dev = wdev->netdev;
1972 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1973 u32 statsClearReqMask;
1974 u8 stopReq;
1975 int status;
1976
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301977 ENTER();
1978
Sunil Duttc69bccb2014-05-26 21:30:20 +05301979 status = wlan_hdd_validate_context(pHddCtx);
1980 if (0 != status)
1981 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301982 return -EINVAL;
1983 }
1984
1985 if (NULL == pAdapter)
1986 {
1987 hddLog(VOS_TRACE_LEVEL_FATAL,
1988 "%s: HDD adapter is Null", __func__);
1989 return -ENODEV;
1990 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301991 /* check the LLStats Capability */
1992 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1993 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1994 {
1995 hddLog(VOS_TRACE_LEVEL_ERROR,
1996 FL("Enable LLStats Capability"));
1997 return -EINVAL;
1998 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301999
2000 if (!pAdapter->isLinkLayerStatsSet)
2001 {
2002 hddLog(VOS_TRACE_LEVEL_FATAL,
2003 "%s: isLinkLayerStatsSet : %d",
2004 __func__, pAdapter->isLinkLayerStatsSet);
2005 return -EINVAL;
2006 }
2007
2008 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2009 (struct nlattr *)data,
2010 data_len, qca_wlan_vendor_ll_clr_policy))
2011 {
2012 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2013 return -EINVAL;
2014 }
2015
2016 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2017
2018 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2019 {
2020 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2021 return -EINVAL;
2022
2023 }
2024
Sunil Duttc69bccb2014-05-26 21:30:20 +05302025
Dino Mycledf0a5d92014-07-04 09:41:55 +05302026 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302027 nla_get_u32(
2028 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2029
Dino Mycledf0a5d92014-07-04 09:41:55 +05302030 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302031 nla_get_u8(
2032 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2033
2034 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302035 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302036
Dino Mycled3d50022014-07-07 12:58:25 +05302037 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2038 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302039
2040 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302041 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2042 "statsClearReqMask = 0x%X, stopReq = %d",
2043 linkLayerStatsClearReq.reqId,
2044 linkLayerStatsClearReq.macAddr,
2045 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302046 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302047
2048 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302049 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302050 {
2051 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302052 hdd_station_ctx_t *pHddStaCtx;
2053
2054 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2055 if (VOS_STATUS_SUCCESS !=
2056 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2057 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2058 {
2059 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2060 "WLANTL_ClearInterfaceStats Failed", __func__);
2061 return -EINVAL;
2062 }
2063 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2064 (statsClearReqMask & WIFI_STATS_IFACE)) {
2065 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2066 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2067 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2068 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2069 }
2070
Sunil Duttc69bccb2014-05-26 21:30:20 +05302071 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2072 2 * sizeof(u32) +
2073 NLMSG_HDRLEN);
2074
2075 if (temp_skbuff != NULL)
2076 {
2077
2078 if (nla_put_u32(temp_skbuff,
2079 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2080 statsClearReqMask) ||
2081 nla_put_u32(temp_skbuff,
2082 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2083 stopReq))
2084 {
2085 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2086 kfree_skb(temp_skbuff);
2087 return -EINVAL;
2088 }
2089 /* If the ask is to stop the stats collection as part of clear
2090 * (stopReq = 1) , ensure that no further requests of get
2091 * go to the firmware by having isLinkLayerStatsSet set to 0.
2092 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302093 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302094 * case the firmware is just asked to clear the statistics.
2095 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302096 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302097 pAdapter->isLinkLayerStatsSet = 0;
2098 return cfg80211_vendor_cmd_reply(temp_skbuff);
2099 }
2100 return -ENOMEM;
2101 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302102
2103 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302104 return -EINVAL;
2105}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302106static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2107 struct wireless_dev *wdev,
2108 const void *data,
2109 int data_len)
2110{
2111 int ret = 0;
2112
2113 vos_ssr_protect(__func__);
2114 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2115 vos_ssr_unprotect(__func__);
2116
2117 return ret;
2118
2119
2120}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302121#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2122
Dino Mycle6fb96c12014-06-10 11:52:40 +05302123#ifdef WLAN_FEATURE_EXTSCAN
2124static const struct nla_policy
2125wlan_hdd_extscan_config_policy
2126 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2127{
2128 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2129 { .type = NLA_U32 },
2130 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2131 { .type = NLA_U32 },
2132 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2133 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2134 { .type = NLA_U32 },
2135 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2136 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2137
2138 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2139 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2140 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2141 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2142 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302143 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2144 { .type = NLA_U32 },
2145 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2146 { .type = NLA_U32 },
2147 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2148 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302149 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2150 { .type = NLA_U32 },
2151 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2152 { .type = NLA_U32 },
2153 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2154 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302155 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2156 { .type = NLA_U8 },
2157 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302158 { .type = NLA_U8 },
2159 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2160 { .type = NLA_U8 },
2161 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2162 { .type = NLA_U8 },
2163
2164 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2165 { .type = NLA_U32 },
2166 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2167 { .type = NLA_UNSPEC },
2168 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2169 { .type = NLA_S32 },
2170 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2171 { .type = NLA_S32 },
2172 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2173 { .type = NLA_U32 },
2174 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2175 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302176 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2177 { .type = NLA_U32 },
2178 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2179 { .type = NLA_BINARY,
2180 .len = IEEE80211_MAX_SSID_LEN + 1 },
2181 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302182 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302183 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2184 { .type = NLA_U32 },
2185 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2186 { .type = NLA_U8 },
2187 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2188 { .type = NLA_S32 },
2189 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2190 { .type = NLA_S32 },
2191 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2192 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302193};
2194
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302195/**
2196 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2197 * @ctx: hdd global context
2198 * @data: capabilities data
2199 *
2200 * Return: none
2201 */
2202static void
2203wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302204{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302205 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302206 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302207 tSirEXTScanCapabilitiesEvent *data =
2208 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302209
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302210 ENTER();
2211
2212 if (wlan_hdd_validate_context(pHddCtx))
2213 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302214 return;
2215 }
2216
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302217 if (!pMsg)
2218 {
2219 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2220 return;
2221 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302222
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302223 vos_spin_lock_acquire(&hdd_context_lock);
2224
2225 context = &pHddCtx->ext_scan_context;
2226 /* validate response received from target*/
2227 if (context->request_id != data->requestId)
2228 {
2229 vos_spin_lock_release(&hdd_context_lock);
2230 hddLog(LOGE,
2231 FL("Target response id did not match: request_id %d resposne_id %d"),
2232 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302233 return;
2234 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302235 else
2236 {
2237 context->capability_response = *data;
2238 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302239 }
2240
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302241 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302242
Dino Mycle6fb96c12014-06-10 11:52:40 +05302243 return;
2244}
2245
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302246/*
2247 * define short names for the global vendor params
2248 * used by wlan_hdd_send_ext_scan_capability()
2249 */
2250#define PARAM_REQUEST_ID \
2251 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2252#define PARAM_STATUS \
2253 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2254#define MAX_SCAN_CACHE_SIZE \
2255 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2256#define MAX_SCAN_BUCKETS \
2257 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2258#define MAX_AP_CACHE_PER_SCAN \
2259 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2260#define MAX_RSSI_SAMPLE_SIZE \
2261 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2262#define MAX_SCAN_RPT_THRHOLD \
2263 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2264#define MAX_HOTLIST_BSSIDS \
2265 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2266#define MAX_BSSID_HISTORY_ENTRIES \
2267 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2268#define MAX_HOTLIST_SSIDS \
2269 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302270#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2271 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302272
2273static int wlan_hdd_send_ext_scan_capability(void *ctx)
2274{
2275 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2276 struct sk_buff *skb = NULL;
2277 int ret;
2278 tSirEXTScanCapabilitiesEvent *data;
2279 tANI_U32 nl_buf_len;
2280
2281 ret = wlan_hdd_validate_context(pHddCtx);
2282 if (0 != ret)
2283 {
2284 return ret;
2285 }
2286
2287 data = &(pHddCtx->ext_scan_context.capability_response);
2288
2289 nl_buf_len = NLMSG_HDRLEN;
2290 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2291 (sizeof(data->status) + NLA_HDRLEN) +
2292 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2293 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2294 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2295 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2296 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2297 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2298 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2299 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2300
2301 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2302
2303 if (!skb)
2304 {
2305 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2306 return -ENOMEM;
2307 }
2308
2309 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2310 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2311 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2312 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2313 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2314 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2315 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2316 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2317
2318 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2319 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2320 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2321 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2322 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2323 data->maxApPerScan) ||
2324 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2325 data->maxRssiSampleSize) ||
2326 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2327 data->maxScanReportingThreshold) ||
2328 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2329 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2330 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302331 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2332 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302333 {
2334 hddLog(LOGE, FL("nla put fail"));
2335 goto nla_put_failure;
2336 }
2337
2338 cfg80211_vendor_cmd_reply(skb);
2339 return 0;
2340
2341nla_put_failure:
2342 kfree_skb(skb);
2343 return -EINVAL;;
2344}
2345
2346/*
2347 * done with short names for the global vendor params
2348 * used by wlan_hdd_send_ext_scan_capability()
2349 */
2350#undef PARAM_REQUEST_ID
2351#undef PARAM_STATUS
2352#undef MAX_SCAN_CACHE_SIZE
2353#undef MAX_SCAN_BUCKETS
2354#undef MAX_AP_CACHE_PER_SCAN
2355#undef MAX_RSSI_SAMPLE_SIZE
2356#undef MAX_SCAN_RPT_THRHOLD
2357#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302358#undef MAX_BSSID_HISTORY_ENTRIES
2359#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302360
2361static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2362{
2363 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2364 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302365 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302366 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302367
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302368 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302369
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302370 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302371 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302372
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302373 if (!pMsg)
2374 {
2375 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302376 return;
2377 }
2378
Dino Mycle6fb96c12014-06-10 11:52:40 +05302379 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2380 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2381
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302382 context = &pHddCtx->ext_scan_context;
2383 spin_lock(&hdd_context_lock);
2384 if (context->request_id == pData->requestId) {
2385 context->response_status = pData->status ? -EINVAL : 0;
2386 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302387 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302388 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302389
2390 /*
2391 * Store the Request ID for comparing with the requestID obtained
2392 * in other requests.HDD shall return a failure is the extscan_stop
2393 * request is issued with a different requestId as that of the
2394 * extscan_start request. Also, This requestId shall be used while
2395 * indicating the full scan results to the upper layers.
2396 * The requestId is stored with the assumption that the firmware
2397 * shall return the ext scan start request's requestId in ext scan
2398 * start response.
2399 */
2400 if (pData->status == 0)
2401 pMac->sme.extScanStartReqId = pData->requestId;
2402
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302403 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302404 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302405}
2406
2407
2408static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2409{
2410 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2411 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302412 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302413
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302414 ENTER();
2415
2416 if (wlan_hdd_validate_context(pHddCtx)){
2417 return;
2418 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302419
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302420 if (!pMsg)
2421 {
2422 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302423 return;
2424 }
2425
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302426 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2427 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302428
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302429 context = &pHddCtx->ext_scan_context;
2430 spin_lock(&hdd_context_lock);
2431 if (context->request_id == pData->requestId) {
2432 context->response_status = pData->status ? -EINVAL : 0;
2433 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302434 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302435 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302436
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302437 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302438 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302439}
2440
Dino Mycle6fb96c12014-06-10 11:52:40 +05302441static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2442 void *pMsg)
2443{
2444 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302445 tpSirEXTScanSetBssidHotListRspParams pData =
2446 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302447 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302448
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302449 ENTER();
2450
2451 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302452 return;
2453 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302454
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302455 if (!pMsg)
2456 {
2457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2458 return;
2459 }
2460
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302461 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2462 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302463
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302464 context = &pHddCtx->ext_scan_context;
2465 spin_lock(&hdd_context_lock);
2466 if (context->request_id == pData->requestId) {
2467 context->response_status = pData->status ? -EINVAL : 0;
2468 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302469 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302470 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302471
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302472 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302473 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302474}
2475
2476static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2477 void *pMsg)
2478{
2479 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302480 tpSirEXTScanResetBssidHotlistRspParams pData =
2481 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302482 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302483
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302484 ENTER();
2485
2486 if (wlan_hdd_validate_context(pHddCtx)) {
2487 return;
2488 }
2489 if (!pMsg)
2490 {
2491 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302492 return;
2493 }
2494
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302495 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2496 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302497
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302498 context = &pHddCtx->ext_scan_context;
2499 spin_lock(&hdd_context_lock);
2500 if (context->request_id == pData->requestId) {
2501 context->response_status = pData->status ? -EINVAL : 0;
2502 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302503 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302504 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302505
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302506 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302507 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302508}
2509
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302510static void wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(void *ctx,
2511 void *pMsg)
2512{
2513 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2514 tpSirEXTScanSetSsidHotListRspParams pData =
2515 (tpSirEXTScanSetSsidHotListRspParams) pMsg;
2516 struct hdd_ext_scan_context *context;
2517
2518 if (wlan_hdd_validate_context(pHddCtx)){
2519 return;
2520 }
2521
2522 if (!pMsg)
2523 {
2524 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2525 return;
2526 }
2527
2528 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2529 pData->status);
2530
2531 context = &pHddCtx->ext_scan_context;
2532 spin_lock(&hdd_context_lock);
2533 if (context->request_id == pData->requestId) {
2534 context->response_status = pData->status ? -EINVAL : 0;
2535 complete(&context->response_event);
2536 }
2537 spin_unlock(&hdd_context_lock);
2538
2539 return;
2540}
2541
2542static void wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(void *ctx,
2543 void *pMsg)
2544{
2545 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2546 tpSirEXTScanResetSsidHotlistRspParams pData =
2547 (tpSirEXTScanResetSsidHotlistRspParams) pMsg;
2548 struct hdd_ext_scan_context *context;
2549
2550 if (wlan_hdd_validate_context(pHddCtx)) {
2551 return;
2552 }
2553 if (!pMsg)
2554 {
2555 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2556 return;
2557 }
2558
2559 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2560 pData->status);
2561
2562 context = &pHddCtx->ext_scan_context;
2563 spin_lock(&hdd_context_lock);
2564 if (context->request_id == pData->requestId) {
2565 context->response_status = pData->status ? -EINVAL : 0;
2566 complete(&context->response_event);
2567 }
2568 spin_unlock(&hdd_context_lock);
2569
2570 return;
2571}
2572
2573
Dino Mycle6fb96c12014-06-10 11:52:40 +05302574static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2575 void *pMsg)
2576{
2577 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2578 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302579 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302580 tANI_S32 totalResults;
2581 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302582 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
2583 struct hdd_ext_scan_context *context;
2584 bool ignore_cached_results = false;
2585 tExtscanCachedScanResult *result;
2586 struct nlattr *nla_results;
2587 tANI_U16 ieLength= 0;
2588 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302589
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302590 ENTER();
2591
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302592 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302593 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302594
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302595 if (!pMsg)
2596 {
2597 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2598 return;
2599 }
2600
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302601 spin_lock(&hdd_context_lock);
2602 context = &pHddCtx->ext_scan_context;
2603 ignore_cached_results = context->ignore_cached_results;
2604 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302605
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302606 if (ignore_cached_results) {
2607 hddLog(LOGE,
2608 FL("Ignore the cached results received after timeout"));
2609 return;
2610 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302611
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302612 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
2613 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302614
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302615 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302616
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302617 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
2618 scan_id_index++) {
2619 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302620
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302621 totalResults = result->num_results;
2622 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
2623 result->scan_id, result->flags, totalResults);
2624 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302625
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302626 do{
2627 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2628 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2629 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302630
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302631 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2632 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
2633
2634 if (!skb) {
2635 hddLog(VOS_TRACE_LEVEL_ERROR,
2636 FL("cfg80211_vendor_event_alloc failed"));
2637 return;
2638 }
2639
2640 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2641
2642 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2643 pData->requestId) ||
2644 nla_put_u32(skb,
2645 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2646 resultsPerEvent)) {
2647 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2648 goto fail;
2649 }
2650 if (nla_put_u8(skb,
2651 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2652 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302653 {
2654 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2655 goto fail;
2656 }
2657
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302658 if (nla_put_u32(skb,
2659 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2660 result->scan_id)) {
2661 hddLog(LOGE, FL("put fail"));
2662 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302663 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302664
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302665 nla_results = nla_nest_start(skb,
2666 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
2667 if (!nla_results)
2668 goto fail;
2669
2670 if (resultsPerEvent) {
2671 struct nlattr *aps;
2672 struct nlattr *nla_result;
2673
2674 nla_result = nla_nest_start(skb, scan_id_index);
2675 if(!nla_result)
2676 goto fail;
2677
2678 if (nla_put_u32(skb,
2679 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2680 result->scan_id) ||
2681 nla_put_u32(skb,
2682 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
2683 result->flags) ||
2684 nla_put_u32(skb,
2685 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2686 totalResults)) {
2687 hddLog(LOGE, FL("put fail"));
2688 goto fail;
2689 }
2690
2691 aps = nla_nest_start(skb,
2692 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2693 if (!aps)
2694 {
2695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2696 goto fail;
2697 }
2698
2699 head_ptr = (tpSirWifiScanResult) &(result->ap);
2700
2701 for (j = 0; j < resultsPerEvent; j++, i++) {
2702 struct nlattr *ap;
2703 pSirWifiScanResult = head_ptr + i;
2704
2705 /*
2706 * Firmware returns timestamp from WiFi turn ON till
2707 * BSSID was cached (in seconds). Add this with
2708 * time gap between system boot up to WiFi turn ON
2709 * to derive the time since boot when the
2710 * BSSID was cached.
2711 */
2712 pSirWifiScanResult->ts += pHddCtx->wifi_turn_on_time_since_boot;
2713 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2714 "Ssid (%s)"
2715 "Bssid: %pM "
2716 "Channel (%u)"
2717 "Rssi (%d)"
2718 "RTT (%u)"
2719 "RTT_SD (%u)"
2720 "Beacon Period %u"
2721 "Capability 0x%x "
2722 "Ie length %d",
2723 i,
2724 pSirWifiScanResult->ts,
2725 pSirWifiScanResult->ssid,
2726 pSirWifiScanResult->bssid,
2727 pSirWifiScanResult->channel,
2728 pSirWifiScanResult->rssi,
2729 pSirWifiScanResult->rtt,
2730 pSirWifiScanResult->rtt_sd,
2731 pSirWifiScanResult->beaconPeriod,
2732 pSirWifiScanResult->capability,
2733 ieLength);
2734
2735 ap = nla_nest_start(skb, j + 1);
2736 if (!ap)
2737 {
2738 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2739 goto fail;
2740 }
2741
2742 if (nla_put_u64(skb,
2743 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2744 pSirWifiScanResult->ts) )
2745 {
2746 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2747 goto fail;
2748 }
2749 if (nla_put(skb,
2750 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2751 sizeof(pSirWifiScanResult->ssid),
2752 pSirWifiScanResult->ssid) )
2753 {
2754 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2755 goto fail;
2756 }
2757 if (nla_put(skb,
2758 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2759 sizeof(pSirWifiScanResult->bssid),
2760 pSirWifiScanResult->bssid) )
2761 {
2762 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2763 goto fail;
2764 }
2765 if (nla_put_u32(skb,
2766 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2767 pSirWifiScanResult->channel) )
2768 {
2769 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2770 goto fail;
2771 }
2772 if (nla_put_s32(skb,
2773 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2774 pSirWifiScanResult->rssi) )
2775 {
2776 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2777 goto fail;
2778 }
2779 if (nla_put_u32(skb,
2780 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2781 pSirWifiScanResult->rtt) )
2782 {
2783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2784 goto fail;
2785 }
2786 if (nla_put_u32(skb,
2787 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2788 pSirWifiScanResult->rtt_sd))
2789 {
2790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2791 goto fail;
2792 }
2793 if (nla_put_u32(skb,
2794 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2795 pSirWifiScanResult->beaconPeriod))
2796 {
2797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2798 goto fail;
2799 }
2800 if (nla_put_u32(skb,
2801 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2802 pSirWifiScanResult->capability))
2803 {
2804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2805 goto fail;
2806 }
2807 if (nla_put_u32(skb,
2808 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2809 ieLength))
2810 {
2811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2812 goto fail;
2813 }
2814
2815 if (ieLength)
2816 if (nla_put(skb,
2817 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2818 ieLength, ie)) {
2819 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2820 goto fail;
2821 }
2822
2823 nla_nest_end(skb, ap);
2824 }
2825 nla_nest_end(skb, aps);
2826 nla_nest_end(skb, nla_result);
2827 }
2828
2829 nla_nest_end(skb, nla_results);
2830
2831 cfg80211_vendor_cmd_reply(skb);
2832
2833 } while (totalResults > 0);
2834 }
2835
2836 if (!pData->moreData) {
2837 spin_lock(&hdd_context_lock);
2838 context->response_status = 0;
2839 complete(&context->response_event);
2840 spin_unlock(&hdd_context_lock);
2841 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302842
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302843 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302844 return;
2845fail:
2846 kfree_skb(skb);
2847 return;
2848}
2849
2850static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2851 void *pMsg)
2852{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302853 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302854 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2855 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302856 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302857
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302858 ENTER();
2859
2860 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302861 hddLog(LOGE,
2862 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302863 return;
2864 }
2865 if (!pMsg)
2866 {
2867 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302868 return;
2869 }
2870
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302871 if (pData->bss_found)
2872 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2873 else
2874 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2875
Dino Mycle6fb96c12014-06-10 11:52:40 +05302876 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302877#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2878 NULL,
2879#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302880 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302881 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302882
2883 if (!skb) {
2884 hddLog(VOS_TRACE_LEVEL_ERROR,
2885 FL("cfg80211_vendor_event_alloc failed"));
2886 return;
2887 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302888
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302889 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2890 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2891 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2892 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2893
2894 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302895 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2896 "Ssid (%s) "
2897 "Bssid (" MAC_ADDRESS_STR ") "
2898 "Channel (%u) "
2899 "Rssi (%d) "
2900 "RTT (%u) "
2901 "RTT_SD (%u) ",
2902 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302903 pData->bssHotlist[i].ts,
2904 pData->bssHotlist[i].ssid,
2905 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2906 pData->bssHotlist[i].channel,
2907 pData->bssHotlist[i].rssi,
2908 pData->bssHotlist[i].rtt,
2909 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302910 }
2911
2912 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2913 pData->requestId) ||
2914 nla_put_u32(skb,
2915 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302916 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302917 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2918 goto fail;
2919 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302920 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302921 struct nlattr *aps;
2922
2923 aps = nla_nest_start(skb,
2924 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2925 if (!aps)
2926 goto fail;
2927
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302928 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302929 struct nlattr *ap;
2930
2931 ap = nla_nest_start(skb, i + 1);
2932 if (!ap)
2933 goto fail;
2934
2935 if (nla_put_u64(skb,
2936 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302937 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302938 nla_put(skb,
2939 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302940 sizeof(pData->bssHotlist[i].ssid),
2941 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302942 nla_put(skb,
2943 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302944 sizeof(pData->bssHotlist[i].bssid),
2945 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302946 nla_put_u32(skb,
2947 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302948 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302949 nla_put_s32(skb,
2950 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302951 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302952 nla_put_u32(skb,
2953 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302954 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302955 nla_put_u32(skb,
2956 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302957 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302958 goto fail;
2959
2960 nla_nest_end(skb, ap);
2961 }
2962 nla_nest_end(skb, aps);
2963
2964 if (nla_put_u8(skb,
2965 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2966 pData->moreData))
2967 goto fail;
2968 }
2969
2970 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302971 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302972 return;
2973
2974fail:
2975 kfree_skb(skb);
2976 return;
2977
2978}
Dino Mycle6fb96c12014-06-10 11:52:40 +05302979
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302980/**
2981 * wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind() -
2982 * Handle an SSID hotlist match event
2983 * @ctx: HDD context registered with SME
2984 * @event: The SSID hotlist match event
2985 *
2986 * This function will take an SSID match event that was generated by
2987 * firmware and will convert it into a cfg80211 vendor event which is
2988 * sent to userspace.
2989 *
2990 * Return: none
2991 */
2992static void
2993wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
2994 void *pMsg)
2995{
2996 hdd_context_t *hdd_ctx = ctx;
2997 struct sk_buff *skb;
2998 tANI_U32 i, index;
2999 tpSirEXTScanSsidHotlistMatch pData = (tpSirEXTScanSsidHotlistMatch) pMsg;
3000
3001 ENTER();
3002
3003 if (wlan_hdd_validate_context(hdd_ctx)) {
3004 hddLog(LOGE,
3005 FL("HDD context is not valid or response"));
3006 return;
3007 }
3008 if (!pMsg)
3009 {
3010 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3011 return;
3012 }
3013
3014 if (pData->ssid_found) {
3015 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX;
3016 hddLog(LOG1, "SSID hotlist found");
3017 } else {
3018 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX;
3019 hddLog(LOG1, "SSID hotlist lost");
3020 }
3021
3022 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
3023#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3024 NULL,
3025#endif
3026 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3027 index, GFP_KERNEL);
3028
3029 if (!skb) {
3030 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
3031 return;
3032 }
3033 hddLog(LOG1, "Req Id %u, Num of SSIDs %u, More Data (%u)",
3034 pData->requestId, pData->numHotlistSsid, pData->moreData);
3035
3036 for (i = 0; i < pData->numHotlistSsid; i++) {
3037 hddLog(LOG1, "[i=%d] Timestamp %llu "
3038 "Ssid: %s "
3039 "Bssid (" MAC_ADDRESS_STR ") "
3040 "Channel %u "
3041 "Rssi %d "
3042 "RTT %u "
3043 "RTT_SD %u",
3044 i,
3045 pData->ssidHotlist[i].ts,
3046 pData->ssidHotlist[i].ssid,
3047 MAC_ADDR_ARRAY(pData->ssidHotlist[i].bssid),
3048 pData->ssidHotlist[i].channel,
3049 pData->ssidHotlist[i].rssi,
3050 pData->ssidHotlist[i].rtt,
3051 pData->ssidHotlist[i].rtt_sd);
3052 }
3053
3054 if (nla_put_u32(skb,
3055 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3056 pData->requestId) ||
3057 nla_put_u32(skb,
3058 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3059 pData->numHotlistSsid)) {
3060 hddLog(LOGE, FL("put fail"));
3061 goto fail;
3062 }
3063
3064 if (pData->numHotlistSsid) {
3065 struct nlattr *aps;
3066 aps = nla_nest_start(skb,
3067 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3068 if (!aps) {
3069 hddLog(LOGE, FL("nest fail"));
3070 goto fail;
3071 }
3072
3073 for (i = 0; i < pData->numHotlistSsid; i++) {
3074 struct nlattr *ap;
3075
3076 ap = nla_nest_start(skb, i);
3077 if (!ap) {
3078 hddLog(LOGE, FL("nest fail"));
3079 goto fail;
3080 }
3081
3082 if (nla_put_u64(skb,
3083 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3084 pData->ssidHotlist[i].ts) ||
3085 nla_put(skb,
3086 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3087 sizeof(pData->ssidHotlist[i].ssid),
3088 pData->ssidHotlist[i].ssid) ||
3089 nla_put(skb,
3090 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3091 sizeof(pData->ssidHotlist[i].bssid),
3092 pData->ssidHotlist[i].bssid) ||
3093 nla_put_u32(skb,
3094 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3095 pData->ssidHotlist[i].channel) ||
3096 nla_put_s32(skb,
3097 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3098 pData->ssidHotlist[i].rssi) ||
3099 nla_put_u32(skb,
3100 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3101 pData->ssidHotlist[i].rtt) ||
3102 nla_put_u32(skb,
3103 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3104 pData->ssidHotlist[i].rtt_sd)) {
3105 hddLog(LOGE, FL("put fail"));
3106 goto fail;
3107 }
3108 nla_nest_end(skb, ap);
3109 }
3110 nla_nest_end(skb, aps);
3111
3112 if (nla_put_u8(skb,
3113 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3114 pData->moreData)) {
3115 hddLog(LOGE, FL("put fail"));
3116 goto fail;
3117 }
3118 }
3119
3120 cfg80211_vendor_event(skb, GFP_KERNEL);
3121 return;
3122
3123fail:
3124 kfree_skb(skb);
3125 return;
3126
3127}
3128
3129
Dino Mycle6fb96c12014-06-10 11:52:40 +05303130static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3131 void *pMsg)
3132{
3133 struct sk_buff *skb;
3134 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3135 tpSirWifiFullScanResultEvent pData =
3136 (tpSirWifiFullScanResultEvent) (pMsg);
3137
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303138 ENTER();
3139
3140 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303141 hddLog(LOGE,
3142 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303143 return;
3144 }
3145 if (!pMsg)
3146 {
3147 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303148 return;
3149 }
3150
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303151 /*
3152 * If the full scan result including IE data exceeds NL 4K size
3153 * limitation, drop that beacon/probe rsp frame.
3154 */
3155 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3156 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3157 return;
3158 }
3159
Dino Mycle6fb96c12014-06-10 11:52:40 +05303160 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303161#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3162 NULL,
3163#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303164 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3165 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3166 GFP_KERNEL);
3167
3168 if (!skb) {
3169 hddLog(VOS_TRACE_LEVEL_ERROR,
3170 FL("cfg80211_vendor_event_alloc failed"));
3171 return;
3172 }
3173
Dino Mycle6fb96c12014-06-10 11:52:40 +05303174 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3175 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3176 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3177 "Ssid (%s)"
3178 "Bssid (" MAC_ADDRESS_STR ")"
3179 "Channel (%u)"
3180 "Rssi (%d)"
3181 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303182 "RTT_SD (%u)"
3183 "Bcn Period %d"
3184 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303185 pData->ap.ts,
3186 pData->ap.ssid,
3187 MAC_ADDR_ARRAY(pData->ap.bssid),
3188 pData->ap.channel,
3189 pData->ap.rssi,
3190 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303191 pData->ap.rtt_sd,
3192 pData->ap.beaconPeriod,
3193 pData->ap.capability);
3194
Dino Mycle6fb96c12014-06-10 11:52:40 +05303195 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3196 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3197 pData->requestId) ||
3198 nla_put_u64(skb,
3199 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3200 pData->ap.ts) ||
3201 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3202 sizeof(pData->ap.ssid),
3203 pData->ap.ssid) ||
3204 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3205 WNI_CFG_BSSID_LEN,
3206 pData->ap.bssid) ||
3207 nla_put_u32(skb,
3208 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3209 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303210 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303211 pData->ap.rssi) ||
3212 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3213 pData->ap.rtt) ||
3214 nla_put_u32(skb,
3215 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3216 pData->ap.rtt_sd) ||
3217 nla_put_u16(skb,
3218 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3219 pData->ap.beaconPeriod) ||
3220 nla_put_u16(skb,
3221 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3222 pData->ap.capability) ||
3223 nla_put_u32(skb,
3224 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303225 pData->ieLength) ||
3226 nla_put_u8(skb,
3227 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3228 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303229 {
3230 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3231 goto nla_put_failure;
3232 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303233
3234 if (pData->ieLength) {
3235 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3236 pData->ieLength,
3237 pData->ie))
3238 {
3239 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3240 goto nla_put_failure;
3241 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303242 }
3243
3244 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303245 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303246 return;
3247
3248nla_put_failure:
3249 kfree_skb(skb);
3250 return;
3251}
3252
3253static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3254 void *pMsg)
3255{
3256 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3257 struct sk_buff *skb = NULL;
3258 tpSirEXTScanResultsAvailableIndParams pData =
3259 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3260
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303261 ENTER();
3262
3263 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303264 hddLog(LOGE,
3265 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303266 return;
3267 }
3268 if (!pMsg)
3269 {
3270 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303271 return;
3272 }
3273
3274 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303275#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3276 NULL,
3277#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303278 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3279 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3280 GFP_KERNEL);
3281
3282 if (!skb) {
3283 hddLog(VOS_TRACE_LEVEL_ERROR,
3284 FL("cfg80211_vendor_event_alloc failed"));
3285 return;
3286 }
3287
Dino Mycle6fb96c12014-06-10 11:52:40 +05303288 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3289 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3290 pData->numResultsAvailable);
3291 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3292 pData->requestId) ||
3293 nla_put_u32(skb,
3294 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3295 pData->numResultsAvailable)) {
3296 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3297 goto nla_put_failure;
3298 }
3299
3300 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303301 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303302 return;
3303
3304nla_put_failure:
3305 kfree_skb(skb);
3306 return;
3307}
3308
3309static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3310{
3311 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3312 struct sk_buff *skb = NULL;
3313 tpSirEXTScanProgressIndParams pData =
3314 (tpSirEXTScanProgressIndParams) pMsg;
3315
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303316 ENTER();
3317
3318 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303319 hddLog(LOGE,
3320 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303321 return;
3322 }
3323 if (!pMsg)
3324 {
3325 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303326 return;
3327 }
3328
3329 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303330#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3331 NULL,
3332#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303333 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3334 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3335 GFP_KERNEL);
3336
3337 if (!skb) {
3338 hddLog(VOS_TRACE_LEVEL_ERROR,
3339 FL("cfg80211_vendor_event_alloc failed"));
3340 return;
3341 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303342 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303343 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3344 pData->extScanEventType);
3345 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3346 pData->status);
3347
3348 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3349 pData->extScanEventType) ||
3350 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303351 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3352 pData->requestId) ||
3353 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303354 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3355 pData->status)) {
3356 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3357 goto nla_put_failure;
3358 }
3359
3360 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303361 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303362 return;
3363
3364nla_put_failure:
3365 kfree_skb(skb);
3366 return;
3367}
3368
3369void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3370 void *pMsg)
3371{
3372 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3373
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303374 ENTER();
3375
Dino Mycle6fb96c12014-06-10 11:52:40 +05303376 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303377 return;
3378 }
3379
3380 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3381
3382
3383 switch(evType) {
3384 case SIR_HAL_EXTSCAN_START_RSP:
3385 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3386 break;
3387
3388 case SIR_HAL_EXTSCAN_STOP_RSP:
3389 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3390 break;
3391 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3392 /* There is no need to send this response to upper layer
3393 Just log the message */
3394 hddLog(VOS_TRACE_LEVEL_INFO,
3395 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3396 break;
3397 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3398 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3399 break;
3400
3401 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3402 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3403 break;
3404
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303405 case SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP:
3406 wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(ctx, pMsg);
3407 break;
3408
3409 case SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP:
3410 wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(ctx, pMsg);
3411 break;
3412
Dino Mycle6fb96c12014-06-10 11:52:40 +05303413 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303414 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303415 break;
3416 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3417 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3418 break;
3419 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3420 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3421 break;
3422 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3423 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3424 break;
3425 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3426 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3427 break;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303428 case SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND:
3429 wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(ctx, pMsg);
3430 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303431 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3432 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3433 break;
3434 default:
3435 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3436 break;
3437 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303438 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303439}
3440
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303441static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3442 struct wireless_dev *wdev,
3443 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303444{
Dino Myclee8843b32014-07-04 14:21:45 +05303445 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303446 struct net_device *dev = wdev->netdev;
3447 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3448 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3449 struct nlattr
3450 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3451 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303452 struct hdd_ext_scan_context *context;
3453 unsigned long rc;
3454 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303455
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303456 ENTER();
3457
Dino Mycle6fb96c12014-06-10 11:52:40 +05303458 status = wlan_hdd_validate_context(pHddCtx);
3459 if (0 != status)
3460 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303461 return -EINVAL;
3462 }
Dino Myclee8843b32014-07-04 14:21:45 +05303463 /* check the EXTScan Capability */
3464 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303465 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3466 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303467 {
3468 hddLog(VOS_TRACE_LEVEL_ERROR,
3469 FL("EXTScan not enabled/supported by Firmware"));
3470 return -EINVAL;
3471 }
3472
Dino Mycle6fb96c12014-06-10 11:52:40 +05303473 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3474 data, dataLen,
3475 wlan_hdd_extscan_config_policy)) {
3476 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3477 return -EINVAL;
3478 }
3479
3480 /* Parse and fetch request Id */
3481 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3482 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3483 return -EINVAL;
3484 }
3485
Dino Myclee8843b32014-07-04 14:21:45 +05303486 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303487 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303488 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303489
Dino Myclee8843b32014-07-04 14:21:45 +05303490 reqMsg.sessionId = pAdapter->sessionId;
3491 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303492
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303493 vos_spin_lock_acquire(&hdd_context_lock);
3494 context = &pHddCtx->ext_scan_context;
3495 context->request_id = reqMsg.requestId;
3496 INIT_COMPLETION(context->response_event);
3497 vos_spin_lock_release(&hdd_context_lock);
3498
Dino Myclee8843b32014-07-04 14:21:45 +05303499 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303500 if (!HAL_STATUS_SUCCESS(status)) {
3501 hddLog(VOS_TRACE_LEVEL_ERROR,
3502 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303503 return -EINVAL;
3504 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303505
3506 rc = wait_for_completion_timeout(&context->response_event,
3507 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3508 if (!rc) {
3509 hddLog(LOGE, FL("Target response timed out"));
3510 return -ETIMEDOUT;
3511 }
3512
3513 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3514 if (ret)
3515 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3516
3517 return ret;
3518
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303519 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303520 return 0;
3521}
3522
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303523static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3524 struct wireless_dev *wdev,
3525 const void *data, int dataLen)
3526{
3527 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303528
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303529 vos_ssr_protect(__func__);
3530 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3531 vos_ssr_unprotect(__func__);
3532
3533 return ret;
3534}
3535
3536static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3537 struct wireless_dev *wdev,
3538 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303539{
Dino Myclee8843b32014-07-04 14:21:45 +05303540 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303541 struct net_device *dev = wdev->netdev;
3542 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3543 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3544 struct nlattr
3545 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3546 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303547 struct hdd_ext_scan_context *context;
3548 unsigned long rc;
3549 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303550
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303551 ENTER();
3552
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303553 if (VOS_FTM_MODE == hdd_get_conparam()) {
3554 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3555 return -EINVAL;
3556 }
3557
Dino Mycle6fb96c12014-06-10 11:52:40 +05303558 status = wlan_hdd_validate_context(pHddCtx);
3559 if (0 != status)
3560 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303561 return -EINVAL;
3562 }
Dino Myclee8843b32014-07-04 14:21:45 +05303563 /* check the EXTScan Capability */
3564 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303565 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3566 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303567 {
3568 hddLog(VOS_TRACE_LEVEL_ERROR,
3569 FL("EXTScan not enabled/supported by Firmware"));
3570 return -EINVAL;
3571 }
3572
Dino Mycle6fb96c12014-06-10 11:52:40 +05303573 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3574 data, dataLen,
3575 wlan_hdd_extscan_config_policy)) {
3576 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3577 return -EINVAL;
3578 }
3579 /* Parse and fetch request Id */
3580 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3581 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3582 return -EINVAL;
3583 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303584
Dino Myclee8843b32014-07-04 14:21:45 +05303585 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303586 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3587
Dino Myclee8843b32014-07-04 14:21:45 +05303588 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303589
Dino Myclee8843b32014-07-04 14:21:45 +05303590 reqMsg.sessionId = pAdapter->sessionId;
3591 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303592
3593 /* Parse and fetch flush parameter */
3594 if (!tb
3595 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3596 {
3597 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3598 goto failed;
3599 }
Dino Myclee8843b32014-07-04 14:21:45 +05303600 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303601 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3602
Dino Myclee8843b32014-07-04 14:21:45 +05303603 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303604
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303605 spin_lock(&hdd_context_lock);
3606 context = &pHddCtx->ext_scan_context;
3607 context->request_id = reqMsg.requestId;
3608 context->ignore_cached_results = false;
3609 INIT_COMPLETION(context->response_event);
3610 spin_unlock(&hdd_context_lock);
3611
Dino Myclee8843b32014-07-04 14:21:45 +05303612 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303613 if (!HAL_STATUS_SUCCESS(status)) {
3614 hddLog(VOS_TRACE_LEVEL_ERROR,
3615 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303616 return -EINVAL;
3617 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303618
3619 rc = wait_for_completion_timeout(&context->response_event,
3620 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3621 if (!rc) {
3622 hddLog(LOGE, FL("Target response timed out"));
3623 retval = -ETIMEDOUT;
3624 spin_lock(&hdd_context_lock);
3625 context->ignore_cached_results = true;
3626 spin_unlock(&hdd_context_lock);
3627 } else {
3628 spin_lock(&hdd_context_lock);
3629 retval = context->response_status;
3630 spin_unlock(&hdd_context_lock);
3631 }
3632
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303633 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303634 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303635
3636failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303637 return -EINVAL;
3638}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303639static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3640 struct wireless_dev *wdev,
3641 const void *data, int dataLen)
3642{
3643 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303644
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303645 vos_ssr_protect(__func__);
3646 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3647 vos_ssr_unprotect(__func__);
3648
3649 return ret;
3650}
3651
3652static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303653 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303654 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303655{
3656 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3657 struct net_device *dev = wdev->netdev;
3658 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3659 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3660 struct nlattr
3661 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3662 struct nlattr
3663 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3664 struct nlattr *apTh;
3665 eHalStatus status;
3666 tANI_U8 i = 0;
3667 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303668 struct hdd_ext_scan_context *context;
3669 tANI_U32 request_id;
3670 unsigned long rc;
3671 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303672
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303673 ENTER();
3674
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303675 if (VOS_FTM_MODE == hdd_get_conparam()) {
3676 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3677 return -EINVAL;
3678 }
3679
Dino Mycle6fb96c12014-06-10 11:52:40 +05303680 status = wlan_hdd_validate_context(pHddCtx);
3681 if (0 != status)
3682 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303683 return -EINVAL;
3684 }
Dino Myclee8843b32014-07-04 14:21:45 +05303685 /* check the EXTScan Capability */
3686 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303687 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3688 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05303689 {
3690 hddLog(VOS_TRACE_LEVEL_ERROR,
3691 FL("EXTScan not enabled/supported by Firmware"));
3692 return -EINVAL;
3693 }
3694
Dino Mycle6fb96c12014-06-10 11:52:40 +05303695 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3696 data, dataLen,
3697 wlan_hdd_extscan_config_policy)) {
3698 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3699 return -EINVAL;
3700 }
3701
3702 /* Parse and fetch request Id */
3703 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3704 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3705 return -EINVAL;
3706 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303707 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3708 vos_mem_malloc(sizeof(*pReqMsg));
3709 if (!pReqMsg) {
3710 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3711 return -ENOMEM;
3712 }
3713
Dino Myclee8843b32014-07-04 14:21:45 +05303714
Dino Mycle6fb96c12014-06-10 11:52:40 +05303715 pReqMsg->requestId = nla_get_u32(
3716 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3717 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3718
3719 /* Parse and fetch number of APs */
3720 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3721 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3722 goto fail;
3723 }
3724
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303725 /* Parse and fetch lost ap sample size */
3726 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3727 hddLog(LOGE, FL("attr lost ap sample size failed"));
3728 goto fail;
3729 }
3730
3731 pReqMsg->lostBssidSampleSize = nla_get_u32(
3732 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3733 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3734
Dino Mycle6fb96c12014-06-10 11:52:40 +05303735 pReqMsg->sessionId = pAdapter->sessionId;
3736 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3737
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303738 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303739 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303740 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303741
3742 nla_for_each_nested(apTh,
3743 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3744 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3745 nla_data(apTh), nla_len(apTh),
3746 NULL)) {
3747 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3748 goto fail;
3749 }
3750
3751 /* Parse and fetch MAC address */
3752 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3753 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3754 goto fail;
3755 }
3756 memcpy(pReqMsg->ap[i].bssid, nla_data(
3757 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3758 sizeof(tSirMacAddr));
3759 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3760
3761 /* Parse and fetch low RSSI */
3762 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3763 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3764 goto fail;
3765 }
3766 pReqMsg->ap[i].low = nla_get_s32(
3767 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3768 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3769
3770 /* Parse and fetch high RSSI */
3771 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3772 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3773 goto fail;
3774 }
3775 pReqMsg->ap[i].high = nla_get_s32(
3776 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3777 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3778 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303779 i++;
3780 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303781
3782 context = &pHddCtx->ext_scan_context;
3783 spin_lock(&hdd_context_lock);
3784 INIT_COMPLETION(context->response_event);
3785 context->request_id = request_id = pReqMsg->requestId;
3786 spin_unlock(&hdd_context_lock);
3787
Dino Mycle6fb96c12014-06-10 11:52:40 +05303788 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3789 if (!HAL_STATUS_SUCCESS(status)) {
3790 hddLog(VOS_TRACE_LEVEL_ERROR,
3791 FL("sme_SetBssHotlist failed(err=%d)"), status);
3792 vos_mem_free(pReqMsg);
3793 return -EINVAL;
3794 }
3795
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303796 /* request was sent -- wait for the response */
3797 rc = wait_for_completion_timeout(&context->response_event,
3798 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3799
3800 if (!rc) {
3801 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3802 retval = -ETIMEDOUT;
3803 } else {
3804 spin_lock(&hdd_context_lock);
3805 if (context->request_id == request_id)
3806 retval = context->response_status;
3807 else
3808 retval = -EINVAL;
3809 spin_unlock(&hdd_context_lock);
3810 }
3811
Dino Myclee8843b32014-07-04 14:21:45 +05303812 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303813 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303814 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303815
3816fail:
3817 vos_mem_free(pReqMsg);
3818 return -EINVAL;
3819}
3820
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303821static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3822 struct wireless_dev *wdev,
3823 const void *data, int dataLen)
3824{
3825 int ret = 0;
3826
3827 vos_ssr_protect(__func__);
3828 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3829 dataLen);
3830 vos_ssr_unprotect(__func__);
3831
3832 return ret;
3833}
3834
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303835/*
3836 * define short names for the global vendor params
3837 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
3838 */
3839#define PARAM_MAX \
3840QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
3841#define PARAM_REQUEST_ID \
3842QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3843#define PARAMS_LOST_SSID_SAMPLE_SIZE \
3844QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE
3845#define PARAMS_NUM_SSID \
3846QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID
3847#define THRESHOLD_PARAM \
3848QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM
3849#define PARAM_SSID \
3850QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID
3851#define PARAM_BAND \
3852QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND
3853#define PARAM_RSSI_LOW \
3854QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW
3855#define PARAM_RSSI_HIGH \
3856QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH
3857
3858/**
3859 * __wlan_hdd_cfg80211_extscan_set_ssid_hotlist() - set ssid hot list
3860 * @wiphy: Pointer to wireless phy
3861 * @wdev: Pointer to wireless device
3862 * @data: Pointer to data
3863 * @data_len: Data length
3864 *
3865 * Return: 0 on success, negative errno on failure
3866 */
3867static int
3868__wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
3869 struct wireless_dev *wdev,
3870 const void *data,
3871 int data_len)
3872{
3873 tSirEXTScanSetSsidHotListReqParams *request;
3874 struct net_device *dev = wdev->netdev;
3875 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3876 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
3877 struct nlattr *tb[PARAM_MAX + 1];
3878 struct nlattr *tb2[PARAM_MAX + 1];
3879 struct nlattr *ssids;
3880 struct hdd_ext_scan_context *context;
3881 uint32_t request_id;
3882 char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1] = {'\0'};
3883 int ssid_len;
3884 eHalStatus status;
3885 int i, rem, retval;
3886 unsigned long rc;
3887
3888 ENTER();
3889
3890 if (VOS_FTM_MODE == hdd_get_conparam()) {
3891 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3892 return -EINVAL;
3893 }
3894
3895 retval = wlan_hdd_validate_context(hdd_ctx);
3896 if (0 != retval) {
3897 hddLog(LOGE, FL("HDD context is not valid"));
3898 return -EINVAL;
3899 }
3900
3901 /* check the EXTScan Capability */
3902 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05303903 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
3904 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303905 {
3906 hddLog(VOS_TRACE_LEVEL_ERROR,
3907 FL("EXTScan not enabled/supported by Firmware"));
3908 return -EINVAL;
3909 }
3910
3911 if (nla_parse(tb, PARAM_MAX,
3912 data, data_len,
3913 wlan_hdd_extscan_config_policy)) {
3914 hddLog(LOGE, FL("Invalid ATTR"));
3915 return -EINVAL;
3916 }
3917
3918 request = vos_mem_malloc(sizeof(*request));
3919 if (!request) {
3920 hddLog(LOGE, FL("vos_mem_malloc failed"));
3921 return -ENOMEM;
3922 }
3923
3924 /* Parse and fetch request Id */
3925 if (!tb[PARAM_REQUEST_ID]) {
3926 hddLog(LOGE, FL("attr request id failed"));
3927 goto fail;
3928 }
3929
3930 request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
3931 hddLog(LOG1, FL("Request Id %d"), request->request_id);
3932
3933 /* Parse and fetch lost SSID sample size */
3934 if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
3935 hddLog(LOGE, FL("attr number of Ssid failed"));
3936 goto fail;
3937 }
3938 request->lost_ssid_sample_size =
3939 nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
3940 hddLog(LOG1, FL("Lost SSID Sample Size %d"),
3941 request->lost_ssid_sample_size);
3942
3943 /* Parse and fetch number of hotlist SSID */
3944 if (!tb[PARAMS_NUM_SSID]) {
3945 hddLog(LOGE, FL("attr number of Ssid failed"));
3946 goto fail;
3947 }
3948 request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
3949 hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
3950
3951 request->session_id = adapter->sessionId;
3952 hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
3953
3954 i = 0;
3955 nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
3956 if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
3957 hddLog(LOGE,
3958 FL("Too Many SSIDs, %d exceeds %d"),
3959 i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
3960 break;
3961 }
3962 if (nla_parse(tb2, PARAM_MAX,
3963 nla_data(ssids), nla_len(ssids),
3964 wlan_hdd_extscan_config_policy)) {
3965 hddLog(LOGE, FL("nla_parse failed"));
3966 goto fail;
3967 }
3968
3969 /* Parse and fetch SSID */
3970 if (!tb2[PARAM_SSID]) {
3971 hddLog(LOGE, FL("attr ssid failed"));
3972 goto fail;
3973 }
3974 nla_memcpy(ssid_string,
3975 tb2[PARAM_SSID],
3976 sizeof(ssid_string));
3977 hddLog(LOG1, FL("SSID %s"),
3978 ssid_string);
3979 ssid_len = strlen(ssid_string);
3980 memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
3981 request->ssid[i].ssid.length = ssid_len;
3982 request->ssid[i].ssid.ssId[ssid_len] = '\0';
3983 hddLog(LOG1, FL("After copying SSID %s"),
3984 request->ssid[i].ssid.ssId);
3985 hddLog(LOG1, FL("After copying length: %d"),
3986 ssid_len);
3987
3988 /* Parse and fetch low RSSI */
3989 if (!tb2[PARAM_BAND]) {
3990 hddLog(LOGE, FL("attr band failed"));
3991 goto fail;
3992 }
3993 request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
3994 hddLog(LOG1, FL("band %d"), request->ssid[i].band);
3995
3996 /* Parse and fetch low RSSI */
3997 if (!tb2[PARAM_RSSI_LOW]) {
3998 hddLog(LOGE, FL("attr low RSSI failed"));
3999 goto fail;
4000 }
4001 request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
4002 hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
4003
4004 /* Parse and fetch high RSSI */
4005 if (!tb2[PARAM_RSSI_HIGH]) {
4006 hddLog(LOGE, FL("attr high RSSI failed"));
4007 goto fail;
4008 }
4009 request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
4010 hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
4011 i++;
4012 }
4013
4014 context = &hdd_ctx->ext_scan_context;
4015 spin_lock(&hdd_context_lock);
4016 INIT_COMPLETION(context->response_event);
4017 context->request_id = request_id = request->request_id;
4018 spin_unlock(&hdd_context_lock);
4019
4020 status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
4021 if (!HAL_STATUS_SUCCESS(status)) {
4022 hddLog(LOGE,
4023 FL("sme_set_ssid_hotlist failed(err=%d)"), status);
4024 goto fail;
4025 }
4026
4027 vos_mem_free(request);
4028
4029 /* request was sent -- wait for the response */
4030 rc = wait_for_completion_timeout(&context->response_event,
4031 msecs_to_jiffies
4032 (WLAN_WAIT_TIME_EXTSCAN));
4033 if (!rc) {
4034 hddLog(LOGE, FL("sme_set_ssid_hotlist timed out"));
4035 retval = -ETIMEDOUT;
4036 } else {
4037 spin_lock(&hdd_context_lock);
4038 if (context->request_id == request_id)
4039 retval = context->response_status;
4040 else
4041 retval = -EINVAL;
4042 spin_unlock(&hdd_context_lock);
4043 }
4044
4045 return retval;
4046
4047fail:
4048 vos_mem_free(request);
4049 return -EINVAL;
4050}
4051
4052/*
4053 * done with short names for the global vendor params
4054 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4055 */
4056#undef PARAM_MAX
4057#undef PARAM_REQUEST_ID
4058#undef PARAMS_NUM_SSID
4059#undef THRESHOLD_PARAM
4060#undef PARAM_SSID
4061#undef PARAM_BAND
4062#undef PARAM_RSSI_LOW
4063#undef PARAM_RSSI_HIGH
4064
4065static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4066 struct wireless_dev *wdev,
4067 const void *data, int dataLen)
4068{
4069 int ret = 0;
4070
4071 vos_ssr_protect(__func__);
4072 ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
4073 dataLen);
4074 vos_ssr_unprotect(__func__);
4075
4076 return ret;
4077}
4078
4079static int
4080__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4081 struct wireless_dev *wdev,
4082 const void *data,
4083 int data_len)
4084{
4085 tSirEXTScanResetSsidHotlistReqParams request;
4086 struct net_device *dev = wdev->netdev;
4087 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4088 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4089 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4090 struct hdd_ext_scan_context *context;
4091 uint32_t request_id;
4092 eHalStatus status;
4093 int retval;
4094 unsigned long rc;
4095
4096 ENTER();
4097
4098 if (VOS_FTM_MODE == hdd_get_conparam()) {
4099 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4100 return -EINVAL;
4101 }
4102
4103 retval = wlan_hdd_validate_context(hdd_ctx);
4104 if (0 != retval) {
4105 hddLog(LOGE, FL("HDD context is not valid"));
4106 return -EINVAL;
4107 }
4108
4109 /* check the EXTScan Capability */
4110 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304111 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4112 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304113 {
4114 hddLog(LOGE,
4115 FL("EXTScan not enabled/supported by Firmware"));
4116 return -EINVAL;
4117 }
4118
4119 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4120 data, data_len,
4121 wlan_hdd_extscan_config_policy)) {
4122 hddLog(LOGE, FL("Invalid ATTR"));
4123 return -EINVAL;
4124 }
4125
4126 /* Parse and fetch request Id */
4127 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4128 hddLog(LOGE, FL("attr request id failed"));
4129 return -EINVAL;
4130 }
4131
4132 request.requestId = nla_get_u32(
4133 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4134 request.sessionId = adapter->sessionId;
4135 hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
4136 request.sessionId);
4137
4138 context = &hdd_ctx->ext_scan_context;
4139 spin_lock(&hdd_context_lock);
4140 INIT_COMPLETION(context->response_event);
4141 context->request_id = request_id = request.requestId;
4142 spin_unlock(&hdd_context_lock);
4143
4144 status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
4145 if (!HAL_STATUS_SUCCESS(status)) {
4146 hddLog(LOGE,
4147 FL("sme_reset_ssid_hotlist failed(err=%d)"), status);
4148 return -EINVAL;
4149 }
4150
4151 /* request was sent -- wait for the response */
4152 rc = wait_for_completion_timeout(&context->response_event,
4153 msecs_to_jiffies
4154 (WLAN_WAIT_TIME_EXTSCAN));
4155 if (!rc) {
4156 hddLog(LOGE, FL("sme_reset_ssid_hotlist timed out"));
4157 retval = -ETIMEDOUT;
4158 } else {
4159 spin_lock(&hdd_context_lock);
4160 if (context->request_id == request_id)
4161 retval = context->response_status;
4162 else
4163 retval = -EINVAL;
4164 spin_unlock(&hdd_context_lock);
4165 }
4166
4167 return retval;
4168}
4169
4170static int
4171wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4172 struct wireless_dev *wdev,
4173 const void *data,
4174 int data_len)
4175{
4176 int ret;
4177
4178 vos_ssr_protect(__func__);
4179 ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
4180 data, data_len);
4181 vos_ssr_unprotect(__func__);
4182
4183 return ret;
4184}
4185
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304186static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304187 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304188 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304189{
4190 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4191 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4192 tANI_U8 numChannels = 0;
4193 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304194 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304195 tWifiBand wifiBand;
4196 eHalStatus status;
4197 struct sk_buff *replySkb;
4198 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304199 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304200
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304201 ENTER();
4202
Dino Mycle6fb96c12014-06-10 11:52:40 +05304203 status = wlan_hdd_validate_context(pHddCtx);
4204 if (0 != status)
4205 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304206 return -EINVAL;
4207 }
Dino Myclee8843b32014-07-04 14:21:45 +05304208
Dino Mycle6fb96c12014-06-10 11:52:40 +05304209 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4210 data, dataLen,
4211 wlan_hdd_extscan_config_policy)) {
4212 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4213 return -EINVAL;
4214 }
4215
4216 /* Parse and fetch request Id */
4217 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4218 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4219 return -EINVAL;
4220 }
4221 requestId = nla_get_u32(
4222 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4223 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4224
4225 /* Parse and fetch wifi band */
4226 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4227 {
4228 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4229 return -EINVAL;
4230 }
4231 wifiBand = nla_get_u32(
4232 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4233 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4234
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304235 /* Parse and fetch max channels */
4236 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4237 {
4238 hddLog(LOGE, FL("attr max channels failed"));
4239 return -EINVAL;
4240 }
4241 maxChannels = nla_get_u32(
4242 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4243 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4244
Dino Mycle6fb96c12014-06-10 11:52:40 +05304245 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
4246 wifiBand, ChannelList,
4247 &numChannels);
4248 if (eHAL_STATUS_SUCCESS != status) {
4249 hddLog(VOS_TRACE_LEVEL_ERROR,
4250 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4251 return -EINVAL;
4252 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304253
4254 numChannels = VOS_MIN(numChannels, maxChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304255 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304256
Dino Mycle6fb96c12014-06-10 11:52:40 +05304257 for (i = 0; i < numChannels; i++)
4258 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
4259
4260 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4261 sizeof(u32) * numChannels +
4262 NLMSG_HDRLEN);
4263
4264 if (!replySkb) {
4265 hddLog(VOS_TRACE_LEVEL_ERROR,
4266 FL("valid channels: buffer alloc fail"));
4267 return -EINVAL;
4268 }
4269 if (nla_put_u32(replySkb,
4270 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
4271 numChannels) ||
4272 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
4273 sizeof(u32) * numChannels, ChannelList)) {
4274
4275 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4276 kfree_skb(replySkb);
4277 return -EINVAL;
4278 }
4279
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304280 ret = cfg80211_vendor_cmd_reply(replySkb);
4281
4282 EXIT();
4283 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304284}
4285
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304286static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4287 struct wireless_dev *wdev,
4288 const void *data, int dataLen)
4289{
4290 int ret = 0;
4291
4292 vos_ssr_protect(__func__);
4293 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4294 dataLen);
4295 vos_ssr_unprotect(__func__);
4296
4297 return ret;
4298}
4299
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304300static int hdd_extscan_start_fill_bucket_channel_spec(
4301 hdd_context_t *pHddCtx,
4302 tpSirEXTScanStartReqParams pReqMsg,
4303 struct nlattr **tb)
4304{
4305 struct nlattr *bucket[
4306 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4307 struct nlattr *channel[
4308 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4309 struct nlattr *buckets;
4310 struct nlattr *channels;
4311 int rem1, rem2;
4312 eHalStatus status;
4313 tANI_U8 bktIndex, j, numChannels;
4314 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4315 tANI_U32 passive_max_chn_time, active_max_chn_time;
4316
4317 bktIndex = 0;
4318
4319 nla_for_each_nested(buckets,
4320 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4321 if (nla_parse(bucket,
4322 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4323 nla_data(buckets), nla_len(buckets), NULL)) {
4324 hddLog(LOGE, FL("nla_parse failed"));
4325 return -EINVAL;
4326 }
4327
4328 /* Parse and fetch bucket spec */
4329 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4330 hddLog(LOGE, FL("attr bucket index failed"));
4331 return -EINVAL;
4332 }
4333 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4334 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4335 hddLog(LOG1, FL("Bucket spec Index %d"),
4336 pReqMsg->buckets[bktIndex].bucket);
4337
4338 /* Parse and fetch wifi band */
4339 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4340 hddLog(LOGE, FL("attr wifi band failed"));
4341 return -EINVAL;
4342 }
4343 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4344 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4345 hddLog(LOG1, FL("Wifi band %d"),
4346 pReqMsg->buckets[bktIndex].band);
4347
4348 /* Parse and fetch period */
4349 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4350 hddLog(LOGE, FL("attr period failed"));
4351 return -EINVAL;
4352 }
4353 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4354 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4355 hddLog(LOG1, FL("period %d"),
4356 pReqMsg->buckets[bktIndex].period);
4357
4358 /* Parse and fetch report events */
4359 if (!bucket[
4360 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4361 hddLog(LOGE, FL("attr report events failed"));
4362 return -EINVAL;
4363 }
4364 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4365 bucket[
4366 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4367 hddLog(LOG1, FL("report events %d"),
4368 pReqMsg->buckets[bktIndex].reportEvents);
4369
4370 /* Parse and fetch max period */
4371 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4372 hddLog(LOGE, FL("attr max period failed"));
4373 return -EINVAL;
4374 }
4375 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4376 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4377 hddLog(LOG1, FL("max period %u"),
4378 pReqMsg->buckets[bktIndex].max_period);
4379
4380 /* Parse and fetch exponent */
4381 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4382 hddLog(LOGE, FL("attr exponent failed"));
4383 return -EINVAL;
4384 }
4385 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4386 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4387 hddLog(LOG1, FL("exponent %u"),
4388 pReqMsg->buckets[bktIndex].exponent);
4389
4390 /* Parse and fetch step count */
4391 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4392 hddLog(LOGE, FL("attr step count failed"));
4393 return -EINVAL;
4394 }
4395 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4396 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4397 hddLog(LOG1, FL("Step count %u"),
4398 pReqMsg->buckets[bktIndex].step_count);
4399
4400 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4401 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4402
4403 /* Framework shall pass the channel list if the input WiFi band is
4404 * WIFI_BAND_UNSPECIFIED.
4405 * If the input WiFi band is specified (any value other than
4406 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4407 */
4408 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4409 numChannels = 0;
4410 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4411 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4412 pReqMsg->buckets[bktIndex].band,
4413 chanList, &numChannels);
4414 if (!HAL_STATUS_SUCCESS(status)) {
4415 hddLog(LOGE,
4416 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4417 status);
4418 return -EINVAL;
4419 }
4420
4421 pReqMsg->buckets[bktIndex].numChannels =
4422 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4423 hddLog(LOG1, FL("Num channels %d"),
4424 pReqMsg->buckets[bktIndex].numChannels);
4425
4426 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4427 j++) {
4428 pReqMsg->buckets[bktIndex].channels[j].channel =
4429 chanList[j];
4430 pReqMsg->buckets[bktIndex].channels[j].
4431 chnlClass = 0;
4432 if (CSR_IS_CHANNEL_DFS(
4433 vos_freq_to_chan(chanList[j]))) {
4434 pReqMsg->buckets[bktIndex].channels[j].
4435 passive = 1;
4436 pReqMsg->buckets[bktIndex].channels[j].
4437 dwellTimeMs = passive_max_chn_time;
4438 } else {
4439 pReqMsg->buckets[bktIndex].channels[j].
4440 passive = 0;
4441 pReqMsg->buckets[bktIndex].channels[j].
4442 dwellTimeMs = active_max_chn_time;
4443 }
4444
4445 hddLog(LOG1,
4446 "Channel %u Passive %u Dwell time %u ms",
4447 pReqMsg->buckets[bktIndex].channels[j].channel,
4448 pReqMsg->buckets[bktIndex].channels[j].passive,
4449 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4450 }
4451
4452 bktIndex++;
4453 continue;
4454 }
4455
4456 /* Parse and fetch number of channels */
4457 if (!bucket[
4458 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4459 hddLog(LOGE, FL("attr num channels failed"));
4460 return -EINVAL;
4461 }
4462
4463 pReqMsg->buckets[bktIndex].numChannels =
4464 nla_get_u32(bucket[
4465 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4466 hddLog(LOG1, FL("num channels %d"),
4467 pReqMsg->buckets[bktIndex].numChannels);
4468
4469 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4470 hddLog(LOGE, FL("attr channel spec failed"));
4471 return -EINVAL;
4472 }
4473
4474 j = 0;
4475 nla_for_each_nested(channels,
4476 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4477 if (nla_parse(channel,
4478 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4479 nla_data(channels), nla_len(channels),
4480 wlan_hdd_extscan_config_policy)) {
4481 hddLog(LOGE, FL("nla_parse failed"));
4482 return -EINVAL;
4483 }
4484
4485 /* Parse and fetch channel */
4486 if (!channel[
4487 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4488 hddLog(LOGE, FL("attr channel failed"));
4489 return -EINVAL;
4490 }
4491 pReqMsg->buckets[bktIndex].channels[j].channel =
4492 nla_get_u32(channel[
4493 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4494 hddLog(LOG1, FL("channel %u"),
4495 pReqMsg->buckets[bktIndex].channels[j].channel);
4496
4497 /* Parse and fetch dwell time */
4498 if (!channel[
4499 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4500 hddLog(LOGE, FL("attr dwelltime failed"));
4501 return -EINVAL;
4502 }
4503 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4504 nla_get_u32(channel[
4505 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4506
4507 hddLog(LOG1, FL("Dwell time (%u ms)"),
4508 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4509
4510
4511 /* Parse and fetch channel spec passive */
4512 if (!channel[
4513 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4514 hddLog(LOGE,
4515 FL("attr channel spec passive failed"));
4516 return -EINVAL;
4517 }
4518 pReqMsg->buckets[bktIndex].channels[j].passive =
4519 nla_get_u8(channel[
4520 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4521 hddLog(LOG1, FL("Chnl spec passive %u"),
4522 pReqMsg->buckets[bktIndex].channels[j].passive);
4523
4524 j++;
4525 }
4526
4527 bktIndex++;
4528 }
4529
4530 return 0;
4531}
4532
4533
4534/*
4535 * define short names for the global vendor params
4536 * used by wlan_hdd_cfg80211_extscan_start()
4537 */
4538#define PARAM_MAX \
4539QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4540#define PARAM_REQUEST_ID \
4541QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4542#define PARAM_BASE_PERIOD \
4543QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4544#define PARAM_MAX_AP_PER_SCAN \
4545QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4546#define PARAM_RPT_THRHLD_PERCENT \
4547QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4548#define PARAM_RPT_THRHLD_NUM_SCANS \
4549QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4550#define PARAM_NUM_BUCKETS \
4551QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4552
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304553static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304554 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304555 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304556{
Dino Myclee8843b32014-07-04 14:21:45 +05304557 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304558 struct net_device *dev = wdev->netdev;
4559 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4560 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4561 struct nlattr *tb[PARAM_MAX + 1];
4562 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304563 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304564 tANI_U32 request_id;
4565 struct hdd_ext_scan_context *context;
4566 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304567
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304568 ENTER();
4569
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304570 if (VOS_FTM_MODE == hdd_get_conparam()) {
4571 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4572 return -EINVAL;
4573 }
4574
Dino Mycle6fb96c12014-06-10 11:52:40 +05304575 status = wlan_hdd_validate_context(pHddCtx);
4576 if (0 != status)
4577 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304578 return -EINVAL;
4579 }
Dino Myclee8843b32014-07-04 14:21:45 +05304580 /* check the EXTScan Capability */
4581 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304582 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4583 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304584 {
4585 hddLog(VOS_TRACE_LEVEL_ERROR,
4586 FL("EXTScan not enabled/supported by Firmware"));
4587 return -EINVAL;
4588 }
4589
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304590 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304591 data, dataLen,
4592 wlan_hdd_extscan_config_policy)) {
4593 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4594 return -EINVAL;
4595 }
4596
4597 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304598 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304599 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4600 return -EINVAL;
4601 }
4602
Dino Myclee8843b32014-07-04 14:21:45 +05304603 pReqMsg = (tpSirEXTScanStartReqParams)
4604 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304605 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304606 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4607 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304608 }
4609
4610 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304611 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304612 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4613
4614 pReqMsg->sessionId = pAdapter->sessionId;
4615 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4616
4617 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304618 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304619 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4620 goto fail;
4621 }
4622 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304623 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304624 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4625 pReqMsg->basePeriod);
4626
4627 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304628 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304629 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4630 goto fail;
4631 }
4632 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304633 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304634 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4635 pReqMsg->maxAPperScan);
4636
4637 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304638 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304639 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4640 goto fail;
4641 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304642 pReqMsg->reportThresholdPercent = nla_get_u8(
4643 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304644 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304645 pReqMsg->reportThresholdPercent);
4646
4647 /* Parse and fetch report threshold num scans */
4648 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4649 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4650 goto fail;
4651 }
4652 pReqMsg->reportThresholdNumScans = nla_get_u8(
4653 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4654 hddLog(LOG1, FL("Report Threshold num scans %d"),
4655 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304656
4657 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304658 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304659 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4660 goto fail;
4661 }
4662 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304663 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304664 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4665 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4666 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4667 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4668 }
4669 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4670 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304671
Dino Mycle6fb96c12014-06-10 11:52:40 +05304672 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4673 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4674 goto fail;
4675 }
4676
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304677 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304678
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304679 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4680 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304681
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304682 context = &pHddCtx->ext_scan_context;
4683 spin_lock(&hdd_context_lock);
4684 INIT_COMPLETION(context->response_event);
4685 context->request_id = request_id = pReqMsg->requestId;
4686 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304687
Dino Mycle6fb96c12014-06-10 11:52:40 +05304688 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4689 if (!HAL_STATUS_SUCCESS(status)) {
4690 hddLog(VOS_TRACE_LEVEL_ERROR,
4691 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304692 goto fail;
4693 }
4694
4695 /* request was sent -- wait for the response */
4696 rc = wait_for_completion_timeout(&context->response_event,
4697 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4698
4699 if (!rc) {
4700 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4701 retval = -ETIMEDOUT;
4702 } else {
4703 spin_lock(&hdd_context_lock);
4704 if (context->request_id == request_id)
4705 retval = context->response_status;
4706 else
4707 retval = -EINVAL;
4708 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304709 }
4710
Dino Myclee8843b32014-07-04 14:21:45 +05304711 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304712 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304713 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304714
4715fail:
4716 vos_mem_free(pReqMsg);
4717 return -EINVAL;
4718}
4719
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304720/*
4721 * done with short names for the global vendor params
4722 * used by wlan_hdd_cfg80211_extscan_start()
4723 */
4724#undef PARAM_MAX
4725#undef PARAM_REQUEST_ID
4726#undef PARAM_BASE_PERIOD
4727#undef PARAMS_MAX_AP_PER_SCAN
4728#undef PARAMS_RPT_THRHLD_PERCENT
4729#undef PARAMS_RPT_THRHLD_NUM_SCANS
4730#undef PARAMS_NUM_BUCKETS
4731
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304732static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4733 struct wireless_dev *wdev,
4734 const void *data, int dataLen)
4735{
4736 int ret = 0;
4737
4738 vos_ssr_protect(__func__);
4739 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4740 vos_ssr_unprotect(__func__);
4741
4742 return ret;
4743}
4744
4745static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304746 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304747 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304748{
Dino Myclee8843b32014-07-04 14:21:45 +05304749 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304750 struct net_device *dev = wdev->netdev;
4751 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4752 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4753 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4754 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304755 int retval;
4756 unsigned long rc;
4757 struct hdd_ext_scan_context *context;
4758 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304759
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304760 ENTER();
4761
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304762 if (VOS_FTM_MODE == hdd_get_conparam()) {
4763 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4764 return -EINVAL;
4765 }
4766
Dino Mycle6fb96c12014-06-10 11:52:40 +05304767 status = wlan_hdd_validate_context(pHddCtx);
4768 if (0 != status)
4769 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304770 return -EINVAL;
4771 }
Dino Myclee8843b32014-07-04 14:21:45 +05304772 /* check the EXTScan Capability */
4773 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304774 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4775 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304776 {
4777 hddLog(VOS_TRACE_LEVEL_ERROR,
4778 FL("EXTScan not enabled/supported by Firmware"));
4779 return -EINVAL;
4780 }
4781
Dino Mycle6fb96c12014-06-10 11:52:40 +05304782 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4783 data, dataLen,
4784 wlan_hdd_extscan_config_policy)) {
4785 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4786 return -EINVAL;
4787 }
4788
4789 /* Parse and fetch request Id */
4790 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4791 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4792 return -EINVAL;
4793 }
4794
Dino Myclee8843b32014-07-04 14:21:45 +05304795 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304796 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304797 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304798
Dino Myclee8843b32014-07-04 14:21:45 +05304799 reqMsg.sessionId = pAdapter->sessionId;
4800 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304801
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304802 context = &pHddCtx->ext_scan_context;
4803 spin_lock(&hdd_context_lock);
4804 INIT_COMPLETION(context->response_event);
4805 context->request_id = request_id = reqMsg.sessionId;
4806 spin_unlock(&hdd_context_lock);
4807
Dino Myclee8843b32014-07-04 14:21:45 +05304808 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304809 if (!HAL_STATUS_SUCCESS(status)) {
4810 hddLog(VOS_TRACE_LEVEL_ERROR,
4811 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304812 return -EINVAL;
4813 }
4814
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304815 /* request was sent -- wait for the response */
4816 rc = wait_for_completion_timeout(&context->response_event,
4817 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4818
4819 if (!rc) {
4820 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4821 retval = -ETIMEDOUT;
4822 } else {
4823 spin_lock(&hdd_context_lock);
4824 if (context->request_id == request_id)
4825 retval = context->response_status;
4826 else
4827 retval = -EINVAL;
4828 spin_unlock(&hdd_context_lock);
4829 }
4830
4831 return retval;
4832
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304833 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304834 return 0;
4835}
4836
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304837static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4838 struct wireless_dev *wdev,
4839 const void *data, int dataLen)
4840{
4841 int ret = 0;
4842
4843 vos_ssr_protect(__func__);
4844 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4845 vos_ssr_unprotect(__func__);
4846
4847 return ret;
4848}
4849
4850static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304851 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304852 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304853{
Dino Myclee8843b32014-07-04 14:21:45 +05304854 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304855 struct net_device *dev = wdev->netdev;
4856 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4857 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4858 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4859 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304860 struct hdd_ext_scan_context *context;
4861 tANI_U32 request_id;
4862 unsigned long rc;
4863 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304864
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304865 ENTER();
4866
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304867 if (VOS_FTM_MODE == hdd_get_conparam()) {
4868 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4869 return -EINVAL;
4870 }
4871
Dino Mycle6fb96c12014-06-10 11:52:40 +05304872 status = wlan_hdd_validate_context(pHddCtx);
4873 if (0 != status)
4874 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304875 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304876 return -EINVAL;
4877 }
Dino Myclee8843b32014-07-04 14:21:45 +05304878 /* check the EXTScan Capability */
4879 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05304880 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) ||
4881 (TRUE != sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)))
Dino Myclee8843b32014-07-04 14:21:45 +05304882 {
4883 hddLog(VOS_TRACE_LEVEL_ERROR,
4884 FL("EXTScan not enabled/supported by Firmware"));
4885 return -EINVAL;
4886 }
4887
Dino Mycle6fb96c12014-06-10 11:52:40 +05304888 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4889 data, dataLen,
4890 wlan_hdd_extscan_config_policy)) {
4891 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4892 return -EINVAL;
4893 }
4894
4895 /* Parse and fetch request Id */
4896 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4897 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4898 return -EINVAL;
4899 }
4900
Dino Myclee8843b32014-07-04 14:21:45 +05304901 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304902 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304903 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304904
Dino Myclee8843b32014-07-04 14:21:45 +05304905 reqMsg.sessionId = pAdapter->sessionId;
4906 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304907
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304908 context = &pHddCtx->ext_scan_context;
4909 spin_lock(&hdd_context_lock);
4910 INIT_COMPLETION(context->response_event);
4911 context->request_id = request_id = reqMsg.requestId;
4912 spin_unlock(&hdd_context_lock);
4913
Dino Myclee8843b32014-07-04 14:21:45 +05304914 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304915 if (!HAL_STATUS_SUCCESS(status)) {
4916 hddLog(VOS_TRACE_LEVEL_ERROR,
4917 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304918 return -EINVAL;
4919 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304920
4921 /* request was sent -- wait for the response */
4922 rc = wait_for_completion_timeout(&context->response_event,
4923 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4924 if (!rc) {
4925 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4926 retval = -ETIMEDOUT;
4927 } else {
4928 spin_lock(&hdd_context_lock);
4929 if (context->request_id == request_id)
4930 retval = context->response_status;
4931 else
4932 retval = -EINVAL;
4933 spin_unlock(&hdd_context_lock);
4934 }
4935
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304936 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304937 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304938}
4939
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304940static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4941 struct wireless_dev *wdev,
4942 const void *data, int dataLen)
4943{
4944 int ret = 0;
4945
4946 vos_ssr_protect(__func__);
4947 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4948 vos_ssr_unprotect(__func__);
4949
4950 return ret;
4951}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304952#endif /* WLAN_FEATURE_EXTSCAN */
4953
Atul Mittal115287b2014-07-08 13:26:33 +05304954/*EXT TDLS*/
4955static const struct nla_policy
4956wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4957{
4958 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4959 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4960 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4961 {.type = NLA_S32 },
4962 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4963 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4964
4965};
4966
4967static const struct nla_policy
4968wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4969{
4970 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4971
4972};
4973
4974static const struct nla_policy
4975wlan_hdd_tdls_config_state_change_policy[
4976 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4977{
4978 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4979 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4980 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304981 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4982 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4983 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304984
4985};
4986
4987static const struct nla_policy
4988wlan_hdd_tdls_config_get_status_policy[
4989 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4990{
4991 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4992 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4993 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304994 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4995 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4996 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304997
4998};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304999
5000static const struct nla_policy
5001wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5002{
5003 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
5004};
5005
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305006static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305007 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305008 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305009 int data_len)
5010{
5011
5012 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5013 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5014
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305015 ENTER();
5016
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305017 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305018 return -EINVAL;
5019 }
5020 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305021 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305022 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305023 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305024 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305025 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305026 return -ENOTSUPP;
5027 }
5028
5029 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5030 data, data_len, wlan_hdd_mac_config)) {
5031 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5032 return -EINVAL;
5033 }
5034
5035 /* Parse and fetch mac address */
5036 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5037 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5038 return -EINVAL;
5039 }
5040
5041 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5042 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5043 VOS_MAC_ADDR_LAST_3_BYTES);
5044
Siddharth Bhal76972212014-10-15 16:22:51 +05305045 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5046
5047 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305048 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5049 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305050 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5051 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5052 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5053 {
5054 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5055 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5056 VOS_MAC_ADDRESS_LEN);
5057 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305058 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305059
Siddharth Bhal76972212014-10-15 16:22:51 +05305060 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
5061 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305062 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
5063 }
5064
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305065 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305066 return 0;
5067}
5068
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305069static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5070 struct wireless_dev *wdev,
5071 const void *data,
5072 int data_len)
5073{
5074 int ret = 0;
5075
5076 vos_ssr_protect(__func__);
5077 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5078 vos_ssr_unprotect(__func__);
5079
5080 return ret;
5081}
5082
5083static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305084 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305085 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305086 int data_len)
5087{
5088 u8 peer[6] = {0};
5089 struct net_device *dev = wdev->netdev;
5090 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5091 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5092 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5093 eHalStatus ret;
5094 tANI_S32 state;
5095 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305096 tANI_S32 global_operating_class = 0;
5097 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305098 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305099 int retVal;
5100
5101 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305102
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305103 if (!pAdapter) {
5104 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5105 return -EINVAL;
5106 }
5107
Atul Mittal115287b2014-07-08 13:26:33 +05305108 ret = wlan_hdd_validate_context(pHddCtx);
5109 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305110 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305111 return -EINVAL;
5112 }
5113 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305114 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305115 return -ENOTSUPP;
5116 }
5117 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5118 data, data_len,
5119 wlan_hdd_tdls_config_get_status_policy)) {
5120 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5121 return -EINVAL;
5122 }
5123
5124 /* Parse and fetch mac address */
5125 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5126 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5127 return -EINVAL;
5128 }
5129
5130 memcpy(peer, nla_data(
5131 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5132 sizeof(peer));
5133 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5134
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305135 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305136
Atul Mittal115287b2014-07-08 13:26:33 +05305137 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305138 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305139 NLMSG_HDRLEN);
5140
5141 if (!skb) {
5142 hddLog(VOS_TRACE_LEVEL_ERROR,
5143 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5144 return -EINVAL;
5145 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305146 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 +05305147 reason,
5148 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305149 global_operating_class,
5150 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305151 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305152 if (nla_put_s32(skb,
5153 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5154 state) ||
5155 nla_put_s32(skb,
5156 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5157 reason) ||
5158 nla_put_s32(skb,
5159 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5160 global_operating_class) ||
5161 nla_put_s32(skb,
5162 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5163 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305164
5165 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5166 goto nla_put_failure;
5167 }
5168
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305169 retVal = cfg80211_vendor_cmd_reply(skb);
5170 EXIT();
5171 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305172
5173nla_put_failure:
5174 kfree_skb(skb);
5175 return -EINVAL;
5176}
5177
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305178static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5179 struct wireless_dev *wdev,
5180 const void *data,
5181 int data_len)
5182{
5183 int ret = 0;
5184
5185 vos_ssr_protect(__func__);
5186 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5187 vos_ssr_unprotect(__func__);
5188
5189 return ret;
5190}
5191
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305192static int wlan_hdd_cfg80211_exttdls_callback(
5193#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5194 const tANI_U8* mac,
5195#else
5196 tANI_U8* mac,
5197#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305198 tANI_S32 state,
5199 tANI_S32 reason,
5200 void *ctx)
5201{
5202 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305203 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305204 tANI_S32 global_operating_class = 0;
5205 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305206 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305207
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305208 ENTER();
5209
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305210 if (!pAdapter) {
5211 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5212 return -EINVAL;
5213 }
5214
5215 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305216 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305217 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305218 return -EINVAL;
5219 }
5220
5221 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305222 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305223 return -ENOTSUPP;
5224 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305225 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5226#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5227 NULL,
5228#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305229 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5230 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5231 GFP_KERNEL);
5232
5233 if (!skb) {
5234 hddLog(VOS_TRACE_LEVEL_ERROR,
5235 FL("cfg80211_vendor_event_alloc failed"));
5236 return -EINVAL;
5237 }
5238 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305239 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5240 reason,
5241 state,
5242 global_operating_class,
5243 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305244 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5245 MAC_ADDR_ARRAY(mac));
5246
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305247 if (nla_put(skb,
5248 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5249 VOS_MAC_ADDR_SIZE, mac) ||
5250 nla_put_s32(skb,
5251 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5252 state) ||
5253 nla_put_s32(skb,
5254 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5255 reason) ||
5256 nla_put_s32(skb,
5257 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5258 channel) ||
5259 nla_put_s32(skb,
5260 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5261 global_operating_class)
5262 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305263 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5264 goto nla_put_failure;
5265 }
5266
5267 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305268 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305269 return (0);
5270
5271nla_put_failure:
5272 kfree_skb(skb);
5273 return -EINVAL;
5274}
5275
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305276static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305277 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305278 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305279 int data_len)
5280{
5281 u8 peer[6] = {0};
5282 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305283 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5284 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5285 eHalStatus status;
5286 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305287 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305288 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305289
5290 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305291
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305292 if (!dev) {
5293 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5294 return -EINVAL;
5295 }
5296
5297 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5298 if (!pAdapter) {
5299 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5300 return -EINVAL;
5301 }
5302
Atul Mittal115287b2014-07-08 13:26:33 +05305303 status = wlan_hdd_validate_context(pHddCtx);
5304 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305305 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305306 return -EINVAL;
5307 }
5308 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305309 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305310 return -ENOTSUPP;
5311 }
5312 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5313 data, data_len,
5314 wlan_hdd_tdls_config_enable_policy)) {
5315 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5316 return -EINVAL;
5317 }
5318
5319 /* Parse and fetch mac address */
5320 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5321 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5322 return -EINVAL;
5323 }
5324
5325 memcpy(peer, nla_data(
5326 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5327 sizeof(peer));
5328 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5329
5330 /* Parse and fetch channel */
5331 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5332 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5333 return -EINVAL;
5334 }
5335 pReqMsg.channel = nla_get_s32(
5336 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5337 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5338
5339 /* Parse and fetch global operating class */
5340 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5341 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5342 return -EINVAL;
5343 }
5344 pReqMsg.global_operating_class = nla_get_s32(
5345 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5346 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5347 pReqMsg.global_operating_class);
5348
5349 /* Parse and fetch latency ms */
5350 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5351 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5352 return -EINVAL;
5353 }
5354 pReqMsg.max_latency_ms = nla_get_s32(
5355 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5356 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5357 pReqMsg.max_latency_ms);
5358
5359 /* Parse and fetch required bandwidth kbps */
5360 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5361 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5362 return -EINVAL;
5363 }
5364
5365 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5366 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5367 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5368 pReqMsg.min_bandwidth_kbps);
5369
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305370 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305371 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305372 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305373 wlan_hdd_cfg80211_exttdls_callback);
5374
5375 EXIT();
5376 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305377}
5378
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305379static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5380 struct wireless_dev *wdev,
5381 const void *data,
5382 int data_len)
5383{
5384 int ret = 0;
5385
5386 vos_ssr_protect(__func__);
5387 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5388 vos_ssr_unprotect(__func__);
5389
5390 return ret;
5391}
5392
5393static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305394 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305395 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305396 int data_len)
5397{
5398 u8 peer[6] = {0};
5399 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305400 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5401 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5402 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305403 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305404 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305405
5406 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305407
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305408 if (!dev) {
5409 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5410 return -EINVAL;
5411 }
5412
5413 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5414 if (!pAdapter) {
5415 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5416 return -EINVAL;
5417 }
5418
Atul Mittal115287b2014-07-08 13:26:33 +05305419 status = wlan_hdd_validate_context(pHddCtx);
5420 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305421 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305422 return -EINVAL;
5423 }
5424 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305425 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305426 return -ENOTSUPP;
5427 }
5428 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5429 data, data_len,
5430 wlan_hdd_tdls_config_disable_policy)) {
5431 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5432 return -EINVAL;
5433 }
5434 /* Parse and fetch mac address */
5435 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5436 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5437 return -EINVAL;
5438 }
5439
5440 memcpy(peer, nla_data(
5441 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5442 sizeof(peer));
5443 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5444
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305445 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5446
5447 EXIT();
5448 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305449}
5450
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305451static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5452 struct wireless_dev *wdev,
5453 const void *data,
5454 int data_len)
5455{
5456 int ret = 0;
5457
5458 vos_ssr_protect(__func__);
5459 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5460 vos_ssr_unprotect(__func__);
5461
5462 return ret;
5463}
5464
Dasari Srinivas7875a302014-09-26 17:50:57 +05305465static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305466__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305467 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305468 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305469{
5470 struct net_device *dev = wdev->netdev;
5471 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5472 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5473 struct sk_buff *skb = NULL;
5474 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305475 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305476
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305477 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305478
5479 ret = wlan_hdd_validate_context(pHddCtx);
5480 if (0 != ret)
5481 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305482 return ret;
5483 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305484 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5485 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5486 fset |= WIFI_FEATURE_INFRA;
5487 }
5488
5489 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5490 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5491 fset |= WIFI_FEATURE_INFRA_5G;
5492 }
5493
5494#ifdef WLAN_FEATURE_P2P
5495 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5496 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5497 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5498 fset |= WIFI_FEATURE_P2P;
5499 }
5500#endif
5501
5502 /* Soft-AP is supported currently by default */
5503 fset |= WIFI_FEATURE_SOFT_AP;
5504
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305505 /* HOTSPOT is a supplicant feature, enable it by default */
5506 fset |= WIFI_FEATURE_HOTSPOT;
5507
Dasari Srinivas7875a302014-09-26 17:50:57 +05305508#ifdef WLAN_FEATURE_EXTSCAN
5509 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
Padma, Santhosh Kumar2ac54992015-10-12 18:20:58 +05305510 sme_IsFeatureSupportedByFW(EXTENDED_SCAN) &&
5511 sme_IsFeatureSupportedByFW(EXT_SCAN_ENHANCED)) {
5512 hddLog(LOG1, FL("Enhanced EXTScan is supported by firmware"));
Dasari Srinivas7875a302014-09-26 17:50:57 +05305513 fset |= WIFI_FEATURE_EXTSCAN;
5514 }
5515#endif
5516
Dasari Srinivas7875a302014-09-26 17:50:57 +05305517 if (sme_IsFeatureSupportedByFW(NAN)) {
5518 hddLog(LOG1, FL("NAN is supported by firmware"));
5519 fset |= WIFI_FEATURE_NAN;
5520 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305521
5522 /* D2D RTT is not supported currently by default */
5523 if (sme_IsFeatureSupportedByFW(RTT)) {
5524 hddLog(LOG1, FL("RTT is supported by firmware"));
5525 fset |= WIFI_FEATURE_D2AP_RTT;
5526 }
5527
5528#ifdef FEATURE_WLAN_BATCH_SCAN
5529 if (fset & WIFI_FEATURE_EXTSCAN) {
5530 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5531 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5532 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5533 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5534 fset |= WIFI_FEATURE_BATCH_SCAN;
5535 }
5536#endif
5537
5538#ifdef FEATURE_WLAN_SCAN_PNO
5539 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5540 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5541 hddLog(LOG1, FL("PNO is supported by firmware"));
5542 fset |= WIFI_FEATURE_PNO;
5543 }
5544#endif
5545
5546 /* STA+STA is supported currently by default */
5547 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5548
5549#ifdef FEATURE_WLAN_TDLS
5550 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5551 sme_IsFeatureSupportedByFW(TDLS)) {
5552 hddLog(LOG1, FL("TDLS is supported by firmware"));
5553 fset |= WIFI_FEATURE_TDLS;
5554 }
5555
5556 /* TDLS_OFFCHANNEL is not supported currently by default */
5557#endif
5558
5559#ifdef WLAN_AP_STA_CONCURRENCY
5560 /* AP+STA concurrency is supported currently by default */
5561 fset |= WIFI_FEATURE_AP_STA;
5562#endif
5563
Mukul Sharma5add0532015-08-17 15:57:47 +05305564#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5565 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5566 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5567#endif
5568
Dasari Srinivas7875a302014-09-26 17:50:57 +05305569 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5570 NLMSG_HDRLEN);
5571
5572 if (!skb) {
5573 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5574 return -EINVAL;
5575 }
5576 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5577
5578 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5579 hddLog(LOGE, FL("nla put fail"));
5580 goto nla_put_failure;
5581 }
5582
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305583 ret = cfg80211_vendor_cmd_reply(skb);
5584 EXIT();
5585 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305586
5587nla_put_failure:
5588 kfree_skb(skb);
5589 return -EINVAL;
5590}
5591
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305592static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305593wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5594 struct wireless_dev *wdev,
5595 const void *data, int data_len)
5596{
5597 int ret = 0;
5598
5599 vos_ssr_protect(__func__);
5600 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5601 vos_ssr_unprotect(__func__);
5602
5603 return ret;
5604}
5605
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305606
5607static const struct
5608nla_policy
5609qca_wlan_vendor_wifi_logger_get_ring_data_policy
5610[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5611 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5612 = {.type = NLA_U32 },
5613};
5614
5615static int
5616 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5617 struct wireless_dev *wdev,
5618 const void *data,
5619 int data_len)
5620{
5621 int ret;
5622 VOS_STATUS status;
5623 uint32_t ring_id;
5624 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5625 struct nlattr *tb
5626 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5627
5628 ENTER();
5629
5630 ret = wlan_hdd_validate_context(hdd_ctx);
5631 if (0 != ret) {
5632 return ret;
5633 }
5634
5635 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5636 data, data_len,
5637 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5638 hddLog(LOGE, FL("Invalid attribute"));
5639 return -EINVAL;
5640 }
5641
5642 /* Parse and fetch ring id */
5643 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5644 hddLog(LOGE, FL("attr ATTR failed"));
5645 return -EINVAL;
5646 }
5647
5648 ring_id = nla_get_u32(
5649 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5650
5651 hddLog(LOG1, FL("Bug report triggered by framework"));
5652
5653 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5654 WLAN_LOG_INDICATOR_FRAMEWORK,
5655 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305656 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305657 );
5658 if (VOS_STATUS_SUCCESS != status) {
5659 hddLog(LOGE, FL("Failed to trigger bug report"));
5660
5661 return -EINVAL;
5662 }
5663
5664 return 0;
5665
5666
5667}
5668
5669
5670static int
5671 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5672 struct wireless_dev *wdev,
5673 const void *data,
5674 int data_len)
5675{
5676 int ret = 0;
5677
5678 vos_ssr_protect(__func__);
5679 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5680 wdev, data, data_len);
5681 vos_ssr_unprotect(__func__);
5682
5683 return ret;
5684
5685}
5686
5687
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305688static int
5689__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305690 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305691 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305692{
5693 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5694 uint8_t i, feature_sets, max_feature_sets;
5695 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5696 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305697 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5698 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305699
5700 ENTER();
5701
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305702 ret = wlan_hdd_validate_context(pHddCtx);
5703 if (0 != ret)
5704 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305705 return ret;
5706 }
5707
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305708 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5709 data, data_len, NULL)) {
5710 hddLog(LOGE, FL("Invalid ATTR"));
5711 return -EINVAL;
5712 }
5713
5714 /* Parse and fetch max feature set */
5715 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5716 hddLog(LOGE, FL("Attr max feature set size failed"));
5717 return -EINVAL;
5718 }
5719 max_feature_sets = nla_get_u32(
5720 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5721 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5722
5723 /* Fill feature combination matrix */
5724 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305725 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5726 WIFI_FEATURE_P2P;
5727
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305728 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5729 WIFI_FEATURE_SOFT_AP;
5730
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305731 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5732 WIFI_FEATURE_SOFT_AP;
5733
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305734 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5735 WIFI_FEATURE_SOFT_AP |
5736 WIFI_FEATURE_P2P;
5737
5738 /* Add more feature combinations here */
5739
5740 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5741 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5742 hddLog(LOG1, "Feature set matrix");
5743 for (i = 0; i < feature_sets; i++)
5744 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5745
5746 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5747 sizeof(u32) * feature_sets +
5748 NLMSG_HDRLEN);
5749
5750 if (reply_skb) {
5751 if (nla_put_u32(reply_skb,
5752 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5753 feature_sets) ||
5754 nla_put(reply_skb,
5755 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5756 sizeof(u32) * feature_sets, feature_set_matrix)) {
5757 hddLog(LOGE, FL("nla put fail"));
5758 kfree_skb(reply_skb);
5759 return -EINVAL;
5760 }
5761
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305762 ret = cfg80211_vendor_cmd_reply(reply_skb);
5763 EXIT();
5764 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305765 }
5766 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5767 return -ENOMEM;
5768
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305769}
5770
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305771static int
5772wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5773 struct wireless_dev *wdev,
5774 const void *data, int data_len)
5775{
5776 int ret = 0;
5777
5778 vos_ssr_protect(__func__);
5779 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5780 data_len);
5781 vos_ssr_unprotect(__func__);
5782
5783 return ret;
5784}
5785
c_manjeecfd1efb2015-09-25 19:32:34 +05305786
5787static int
5788__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5789 struct wireless_dev *wdev,
5790 const void *data, int data_len)
5791{
5792 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5793 int ret;
5794 ENTER();
5795
5796 ret = wlan_hdd_validate_context(pHddCtx);
5797 if (0 != ret)
5798 {
5799 return ret;
5800 }
5801
5802 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5803 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5804 {
5805 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5806 return -EINVAL;
5807 }
5808 /*call common API for FW mem dump req*/
5809 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5810
5811 EXIT();
5812 return ret;
5813}
5814
5815/**
5816 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5817 * @wiphy: pointer to wireless wiphy structure.
5818 * @wdev: pointer to wireless_dev structure.
5819 * @data: Pointer to the NL data.
5820 * @data_len:Length of @data
5821 *
5822 * This is called when wlan driver needs to get the firmware memory dump
5823 * via vendor specific command.
5824 *
5825 * Return: 0 on success, error number otherwise.
5826 */
5827
5828static int
5829wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5830 struct wireless_dev *wdev,
5831 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305832{
5833 int ret = 0;
5834 vos_ssr_protect(__func__);
5835 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5836 data_len);
5837 vos_ssr_unprotect(__func__);
5838 return ret;
5839}
c_manjeecfd1efb2015-09-25 19:32:34 +05305840
Sushant Kaushik8e644982015-09-23 12:18:54 +05305841static const struct
5842nla_policy
5843qca_wlan_vendor_wifi_logger_start_policy
5844[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5845 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5846 = {.type = NLA_U32 },
5847 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5848 = {.type = NLA_U32 },
5849 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5850 = {.type = NLA_U32 },
5851};
5852
5853/**
5854 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5855 * or disable the collection of packet statistics from the firmware
5856 * @wiphy: WIPHY structure pointer
5857 * @wdev: Wireless device structure pointer
5858 * @data: Pointer to the data received
5859 * @data_len: Length of the data received
5860 *
5861 * This function is used to enable or disable the collection of packet
5862 * statistics from the firmware
5863 *
5864 * Return: 0 on success and errno on failure
5865 */
5866static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5867 struct wireless_dev *wdev,
5868 const void *data,
5869 int data_len)
5870{
5871 eHalStatus status;
5872 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5873 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5874 tAniWifiStartLog start_log;
5875
5876 status = wlan_hdd_validate_context(hdd_ctx);
5877 if (0 != status) {
5878 return -EINVAL;
5879 }
5880
5881 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5882 data, data_len,
5883 qca_wlan_vendor_wifi_logger_start_policy)) {
5884 hddLog(LOGE, FL("Invalid attribute"));
5885 return -EINVAL;
5886 }
5887
5888 /* Parse and fetch ring id */
5889 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5890 hddLog(LOGE, FL("attr ATTR failed"));
5891 return -EINVAL;
5892 }
5893 start_log.ringId = nla_get_u32(
5894 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5895 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5896
5897 /* Parse and fetch verbose level */
5898 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5899 hddLog(LOGE, FL("attr verbose_level failed"));
5900 return -EINVAL;
5901 }
5902 start_log.verboseLevel = nla_get_u32(
5903 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5904 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5905
5906 /* Parse and fetch flag */
5907 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5908 hddLog(LOGE, FL("attr flag failed"));
5909 return -EINVAL;
5910 }
5911 start_log.flag = nla_get_u32(
5912 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5913 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5914
5915 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305916 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5917 !vos_isPktStatsEnabled()))
5918
Sushant Kaushik8e644982015-09-23 12:18:54 +05305919 {
5920 hddLog(LOGE, FL("per pkt stats not enabled"));
5921 return -EINVAL;
5922 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305923
Sushant Kaushik33200572015-08-05 16:46:20 +05305924 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305925 return 0;
5926}
5927
5928/**
5929 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
5930 * or disable the collection of packet statistics from the firmware
5931 * @wiphy: WIPHY structure pointer
5932 * @wdev: Wireless device structure pointer
5933 * @data: Pointer to the data received
5934 * @data_len: Length of the data received
5935 *
5936 * This function is used to enable or disable the collection of packet
5937 * statistics from the firmware
5938 *
5939 * Return: 0 on success and errno on failure
5940 */
5941static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5942 struct wireless_dev *wdev,
5943 const void *data,
5944 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05305945{
5946 int ret = 0;
5947
5948 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305949
5950 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
5951 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05305952 vos_ssr_unprotect(__func__);
5953
5954 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05305955}
5956
5957
Agarwal Ashish738843c2014-09-25 12:27:56 +05305958static const struct nla_policy
5959wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5960 +1] =
5961{
5962 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5963};
5964
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305965static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305966 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305967 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305968 int data_len)
5969{
5970 struct net_device *dev = wdev->netdev;
5971 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5972 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5973 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5974 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5975 eHalStatus status;
5976 u32 dfsFlag = 0;
5977
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305978 ENTER();
5979
Agarwal Ashish738843c2014-09-25 12:27:56 +05305980 status = wlan_hdd_validate_context(pHddCtx);
5981 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305982 return -EINVAL;
5983 }
5984 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5985 data, data_len,
5986 wlan_hdd_set_no_dfs_flag_config_policy)) {
5987 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5988 return -EINVAL;
5989 }
5990
5991 /* Parse and fetch required bandwidth kbps */
5992 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5993 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5994 return -EINVAL;
5995 }
5996
5997 dfsFlag = nla_get_u32(
5998 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5999 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
6000 dfsFlag);
6001
6002 pHddCtx->disable_dfs_flag = dfsFlag;
6003
6004 sme_disable_dfs_channel(hHal, dfsFlag);
6005 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306006
6007 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05306008 return 0;
6009}
Atul Mittal115287b2014-07-08 13:26:33 +05306010
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306011static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6012 struct wireless_dev *wdev,
6013 const void *data,
6014 int data_len)
6015{
6016 int ret = 0;
6017
6018 vos_ssr_protect(__func__);
6019 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6020 vos_ssr_unprotect(__func__);
6021
6022 return ret;
6023
6024}
6025
Mukul Sharma2a271632014-10-13 14:59:01 +05306026const struct
6027nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6028{
6029 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
6030 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
6031};
6032
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306033static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306034 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306035{
6036
6037 u8 bssid[6] = {0};
6038 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6039 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6040 eHalStatus status = eHAL_STATUS_SUCCESS;
6041 v_U32_t isFwrRoamEnabled = FALSE;
6042 int ret;
6043
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306044 ENTER();
6045
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306046 ret = wlan_hdd_validate_context(pHddCtx);
6047 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306048 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306049 }
6050
6051 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6052 data, data_len,
6053 qca_wlan_vendor_attr);
6054 if (ret){
6055 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6056 return -EINVAL;
6057 }
6058
6059 /* Parse and fetch Enable flag */
6060 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6061 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6062 return -EINVAL;
6063 }
6064
6065 isFwrRoamEnabled = nla_get_u32(
6066 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6067
6068 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6069
6070 /* Parse and fetch bssid */
6071 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6072 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6073 return -EINVAL;
6074 }
6075
6076 memcpy(bssid, nla_data(
6077 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6078 sizeof(bssid));
6079 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6080
6081 //Update roaming
6082 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306083 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05306084 return status;
6085}
6086
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306087static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6088 struct wireless_dev *wdev, const void *data, int data_len)
6089{
6090 int ret = 0;
6091
6092 vos_ssr_protect(__func__);
6093 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6094 vos_ssr_unprotect(__func__);
6095
6096 return ret;
6097}
6098
Sushant Kaushik847890c2015-09-28 16:05:17 +05306099static const struct
6100nla_policy
6101qca_wlan_vendor_get_wifi_info_policy[
6102 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6103 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6104 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6105};
6106
6107
6108/**
6109 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6110 * @wiphy: pointer to wireless wiphy structure.
6111 * @wdev: pointer to wireless_dev structure.
6112 * @data: Pointer to the data to be passed via vendor interface
6113 * @data_len:Length of the data to be passed
6114 *
6115 * This is called when wlan driver needs to send wifi driver related info
6116 * (driver/fw version) to the user space application upon request.
6117 *
6118 * Return: Return the Success or Failure code.
6119 */
6120static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6121 struct wireless_dev *wdev,
6122 const void *data, int data_len)
6123{
6124 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6125 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6126 tSirVersionString version;
6127 uint32 version_len;
6128 uint8 attr;
6129 int status;
6130 struct sk_buff *reply_skb = NULL;
6131
6132 if (VOS_FTM_MODE == hdd_get_conparam()) {
6133 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6134 return -EINVAL;
6135 }
6136
6137 status = wlan_hdd_validate_context(hdd_ctx);
6138 if (0 != status) {
6139 hddLog(LOGE, FL("HDD context is not valid"));
6140 return -EINVAL;
6141 }
6142
6143 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6144 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6145 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6146 return -EINVAL;
6147 }
6148
6149 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6150 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6151 QWLAN_VERSIONSTR);
6152 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6153 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6154 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6155 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6156 hdd_ctx->fw_Version);
6157 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6158 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6159 } else {
6160 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6161 return -EINVAL;
6162 }
6163
6164 version_len = strlen(version);
6165 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6166 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6167 if (!reply_skb) {
6168 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6169 return -ENOMEM;
6170 }
6171
6172 if (nla_put(reply_skb, attr, version_len, version)) {
6173 hddLog(LOGE, FL("nla put fail"));
6174 kfree_skb(reply_skb);
6175 return -EINVAL;
6176 }
6177
6178 return cfg80211_vendor_cmd_reply(reply_skb);
6179}
6180
6181/**
6182 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6183 * @wiphy: pointer to wireless wiphy structure.
6184 * @wdev: pointer to wireless_dev structure.
6185 * @data: Pointer to the data to be passed via vendor interface
6186 * @data_len:Length of the data to be passed
6187 * @data_len: Length of the data received
6188 *
6189 * This function is used to enable or disable the collection of packet
6190 * statistics from the firmware
6191 *
6192 * Return: 0 on success and errno on failure
6193 */
6194
6195static int
6196wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6197 struct wireless_dev *wdev,
6198 const void *data, int data_len)
6199
6200
6201{
6202 int ret = 0;
6203
6204 vos_ssr_protect(__func__);
6205 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6206 wdev, data, data_len);
6207 vos_ssr_unprotect(__func__);
6208
6209 return ret;
6210}
6211
6212
Gupta, Kapil7c34b322015-09-30 13:12:35 +05306213/*
6214 * define short names for the global vendor params
6215 * used by __wlan_hdd_cfg80211_monitor_rssi()
6216 */
6217#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX
6218#define PARAM_REQUEST_ID QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID
6219#define PARAM_CONTROL QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CONTROL
6220#define PARAM_MIN_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MIN_RSSI
6221#define PARAM_MAX_RSSI QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_MAX_RSSI
6222
6223/**---------------------------------------------------------------------------
6224
6225 \brief hdd_rssi_monitor_start_done - callback to be executed when rssi
6226 monitor start is completed successfully.
6227
6228 \return - None
6229
6230 --------------------------------------------------------------------------*/
6231void hdd_rssi_monitor_start_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6232{
6233 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6234
6235 if (NULL == pHddCtx)
6236 {
6237 hddLog(VOS_TRACE_LEVEL_ERROR,
6238 "%s: HDD context is NULL",__func__);
6239 return;
6240 }
6241
6242 if (VOS_STATUS_SUCCESS == status)
6243 {
6244 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor start successful"));
6245 }
6246 else
6247 {
6248 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor start not successful"));
6249 }
6250
6251 return;
6252}
6253
6254/**---------------------------------------------------------------------------
6255
6256 \brief hdd_rssi_monitor_stop_done - callback to be executed when rssi monitor
6257 stop is completed successfully.
6258
6259 \return - None
6260
6261 --------------------------------------------------------------------------*/
6262void hdd_rssi_monitor_stop_done(void *fwRssiMonitorCbContext, VOS_STATUS status)
6263{
6264 hdd_context_t* pHddCtx = (hdd_context_t*)fwRssiMonitorCbContext;
6265
6266 if (NULL == pHddCtx)
6267 {
6268 hddLog(VOS_TRACE_LEVEL_ERROR,
6269 "%s: HDD context is NULL",__func__);
6270 return;
6271 }
6272
6273 if (VOS_STATUS_SUCCESS == status)
6274 {
6275 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rssi Monitor stop successful"));
6276 }
6277 else
6278 {
6279 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Rssi Monitor stop not successful"));
6280 }
6281
6282 return;
6283}
6284
6285/**
6286 * __wlan_hdd_cfg80211_monitor_rssi() - monitor rssi
6287 * @wiphy: Pointer to wireless phy
6288 * @wdev: Pointer to wireless device
6289 * @data: Pointer to data
6290 * @data_len: Data length
6291 *
6292 * Return: 0 on success, negative errno on failure
6293 */
6294
6295static int
6296__wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy,
6297 struct wireless_dev *wdev,
6298 const void *data,
6299 int data_len)
6300{
6301 struct net_device *dev = wdev->netdev;
6302 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
6303 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6304 hdd_station_ctx_t *pHddStaCtx;
6305 struct nlattr *tb[PARAM_MAX + 1];
6306 tpSirRssiMonitorReq pReq;
6307 eHalStatus status;
6308 int ret;
6309 uint32_t control;
6310 static const struct nla_policy policy[PARAM_MAX + 1] = {
6311 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6312 [PARAM_CONTROL] = { .type = NLA_U32 },
6313 [PARAM_MIN_RSSI] = { .type = NLA_S8 },
6314 [PARAM_MAX_RSSI] = { .type = NLA_S8 },
6315 };
6316
6317 ENTER();
6318
6319 ret = wlan_hdd_validate_context(hdd_ctx);
6320 if (0 != ret) {
6321 return -EINVAL;
6322 }
6323
6324 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
6325 hddLog(LOGE, FL("Not in Connected state!"));
6326 return -ENOTSUPP;
6327 }
6328
6329 if (nla_parse(tb, PARAM_MAX, data, data_len, policy)) {
6330 hddLog(LOGE, FL("Invalid ATTR"));
6331 return -EINVAL;
6332 }
6333
6334 if (!tb[PARAM_REQUEST_ID]) {
6335 hddLog(LOGE, FL("attr request id failed"));
6336 return -EINVAL;
6337 }
6338
6339 if (!tb[PARAM_CONTROL]) {
6340 hddLog(LOGE, FL("attr control failed"));
6341 return -EINVAL;
6342 }
6343
6344 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6345
6346 pReq = vos_mem_malloc(sizeof(tSirRssiMonitorReq));
6347 if(NULL == pReq)
6348 {
6349 hddLog(LOGE,
6350 FL("vos_mem_alloc failed "));
6351 return eHAL_STATUS_FAILED_ALLOC;
6352 }
6353 vos_mem_set(pReq, sizeof(tSirRssiMonitorReq), 0);
6354
6355 pReq->requestId = nla_get_u32(tb[PARAM_REQUEST_ID]);
6356 pReq->sessionId = pAdapter->sessionId;
6357 pReq->rssiMonitorCbContext = hdd_ctx;
6358 control = nla_get_u32(tb[PARAM_CONTROL]);
6359 vos_mem_copy( &pReq->currentBssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
6360
6361 hddLog(LOG1, FL("Request Id: %u Session_id: %d Control: %d"),
6362 pReq->requestId, pReq->sessionId, control);
6363
6364 if (control == QCA_WLAN_RSSI_MONITORING_START) {
6365 if (!tb[PARAM_MIN_RSSI]) {
6366 hddLog(LOGE, FL("attr min rssi failed"));
6367 return -EINVAL;
6368 }
6369
6370 if (!tb[PARAM_MAX_RSSI]) {
6371 hddLog(LOGE, FL("attr max rssi failed"));
6372 return -EINVAL;
6373 }
6374
6375 pReq->minRssi = nla_get_s8(tb[PARAM_MIN_RSSI]);
6376 pReq->maxRssi = nla_get_s8(tb[PARAM_MAX_RSSI]);
6377 pReq->rssiMonitorCallback = hdd_rssi_monitor_start_done;
6378
6379 if (!(pReq->minRssi < pReq->maxRssi)) {
6380 hddLog(LOGW, FL("min_rssi: %d must be less than max_rssi: %d"),
6381 pReq->minRssi, pReq->maxRssi);
6382 return -EINVAL;
6383 }
6384 hddLog(LOG1, FL("Min_rssi: %d Max_rssi: %d"),
6385 pReq->minRssi, pReq->maxRssi);
6386 status = sme_StartRssiMonitoring(hdd_ctx->hHal, pReq);
6387
6388 }
6389 else if (control == QCA_WLAN_RSSI_MONITORING_STOP) {
6390 pReq->rssiMonitorCallback = hdd_rssi_monitor_stop_done;
6391 status = sme_StopRssiMonitoring(hdd_ctx->hHal, pReq);
6392 }
6393 else {
6394 hddLog(LOGE, FL("Invalid control cmd: %d"), control);
6395 return -EINVAL;
6396 }
6397
6398 if (!HAL_STATUS_SUCCESS(status)) {
6399 hddLog(LOGE,
6400 FL("sme_set_rssi_monitoring failed(err=%d)"), status);
6401 return -EINVAL;
6402 }
6403
6404 return 0;
6405}
6406
6407/*
6408 * done with short names for the global vendor params
6409 * used by __wlan_hdd_cfg80211_monitor_rssi()
6410 */
6411#undef PARAM_MAX
6412#undef PARAM_CONTROL
6413#undef PARAM_REQUEST_ID
6414#undef PARAM_MAX_RSSI
6415#undef PARAM_MIN_RSSI
6416
6417/**
6418 * wlan_hdd_cfg80211_monitor_rssi() - SSR wrapper to rssi monitoring
6419 * @wiphy: wiphy structure pointer
6420 * @wdev: Wireless device structure pointer
6421 * @data: Pointer to the data received
6422 * @data_len: Length of @data
6423 *
6424 * Return: 0 on success; errno on failure
6425 */
6426static int
6427wlan_hdd_cfg80211_monitor_rssi(struct wiphy *wiphy, struct wireless_dev *wdev,
6428 const void *data, int data_len)
6429{
6430 int ret;
6431
6432 vos_ssr_protect(__func__);
6433 ret = __wlan_hdd_cfg80211_monitor_rssi(wiphy, wdev, data, data_len);
6434 vos_ssr_unprotect(__func__);
6435
6436 return ret;
6437}
6438
6439/**
6440 * hdd_rssi_threshold_breached_cb() - rssi breached NL event
6441 * @hddctx: HDD context
6442 * @data: rssi breached event data
6443 *
6444 * This function reads the rssi breached event %data and fill in the skb with
6445 * NL attributes and send up the NL event.
6446 * This callback execute in atomic context and must not invoke any
6447 * blocking calls.
6448 *
6449 * Return: none
6450 */
6451void hdd_rssi_threshold_breached_cb(void *hddctx,
6452 struct rssi_breach_event *data)
6453{
6454 hdd_context_t *pHddCtx = (hdd_context_t *)hddctx;
6455 int status;
6456 struct sk_buff *skb;
6457
6458 ENTER();
6459 status = wlan_hdd_validate_context(pHddCtx);
6460
6461 if (0 != status) {
6462 return;
6463 }
6464
6465 if (!data) {
6466 hddLog(LOGE, FL("data is null"));
6467 return;
6468 }
6469
6470 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
6471#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6472 NULL,
6473#endif
6474 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
6475 QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX,
6476 GFP_KERNEL);
6477
6478 if (!skb) {
6479 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
6480 return;
6481 }
6482
6483 hddLog(LOG1, "Req Id: %u Current rssi: %d",
6484 data->request_id, data->curr_rssi);
6485 hddLog(LOG1, "Current BSSID: "MAC_ADDRESS_STR,
6486 MAC_ADDR_ARRAY(data->curr_bssid.bytes));
6487
6488 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_REQUEST_ID,
6489 data->request_id) ||
6490 nla_put(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_BSSID,
6491 sizeof(data->curr_bssid), data->curr_bssid.bytes) ||
6492 nla_put_s8(skb, QCA_WLAN_VENDOR_ATTR_RSSI_MONITORING_CUR_RSSI,
6493 data->curr_rssi)) {
6494 hddLog(LOGE, FL("nla put fail"));
6495 goto fail;
6496 }
6497
6498 cfg80211_vendor_event(skb, GFP_KERNEL);
6499 return;
6500
6501fail:
6502 kfree_skb(skb);
6503 return;
6504}
6505
6506
6507
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306508/**
6509 * __wlan_hdd_cfg80211_setband() - set band
6510 * @wiphy: Pointer to wireless phy
6511 * @wdev: Pointer to wireless device
6512 * @data: Pointer to data
6513 * @data_len: Data length
6514 *
6515 * Return: 0 on success, negative errno on failure
6516 */
6517static int
6518__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6519 struct wireless_dev *wdev,
6520 const void *data,
6521 int data_len)
6522{
6523 struct net_device *dev = wdev->netdev;
6524 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6525 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6526 int ret;
6527 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6528 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6529
6530 ENTER();
6531
6532 ret = wlan_hdd_validate_context(hdd_ctx);
6533 if (0 != ret) {
6534 hddLog(LOGE, FL("HDD context is not valid"));
6535 return ret;
6536 }
6537
6538 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6539 policy)) {
6540 hddLog(LOGE, FL("Invalid ATTR"));
6541 return -EINVAL;
6542 }
6543
6544 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6545 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6546 return -EINVAL;
6547 }
6548
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306549 hdd_ctx->isSetBandByNL = TRUE;
6550 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306551 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306552 hdd_ctx->isSetBandByNL = FALSE;
6553
6554 EXIT();
6555 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306556}
6557
6558/**
6559 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6560 * @wiphy: wiphy structure pointer
6561 * @wdev: Wireless device structure pointer
6562 * @data: Pointer to the data received
6563 * @data_len: Length of @data
6564 *
6565 * Return: 0 on success; errno on failure
6566 */
6567static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6568 struct wireless_dev *wdev,
6569 const void *data,
6570 int data_len)
6571{
6572 int ret = 0;
6573
6574 vos_ssr_protect(__func__);
6575 ret = __wlan_hdd_cfg80211_setband(wiphy,
6576 wdev, data, data_len);
6577 vos_ssr_unprotect(__func__);
6578
6579 return ret;
6580}
6581
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05306582#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
6583/**
6584 * hdd_map_req_id_to_pattern_id() - map request id to pattern id
6585 * @hdd_ctx: HDD context
6586 * @request_id: [input] request id
6587 * @pattern_id: [output] pattern id
6588 *
6589 * This function loops through request id to pattern id array
6590 * if the slot is available, store the request id and return pattern id
6591 * if entry exists, return the pattern id
6592 *
6593 * Return: 0 on success and errno on failure
6594 */
6595static int hdd_map_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6596 uint32_t request_id,
6597 uint8_t *pattern_id)
6598{
6599 uint32_t i;
6600
6601 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6602 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6603 {
6604 if (hdd_ctx->op_ctx.op_table[i].request_id == 0)
6605 {
6606 hdd_ctx->op_ctx.op_table[i].request_id = request_id;
6607 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6608 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6609 return 0;
6610 } else if (hdd_ctx->op_ctx.op_table[i].request_id ==
6611 request_id) {
6612 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6613 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6614 return 0;
6615 }
6616 }
6617 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6618 return -EINVAL;
6619}
6620
6621/**
6622 * hdd_unmap_req_id_to_pattern_id() - unmap request id to pattern id
6623 * @hdd_ctx: HDD context
6624 * @request_id: [input] request id
6625 * @pattern_id: [output] pattern id
6626 *
6627 * This function loops through request id to pattern id array
6628 * reset request id to 0 (slot available again) and
6629 * return pattern id
6630 *
6631 * Return: 0 on success and errno on failure
6632 */
6633static int hdd_unmap_req_id_to_pattern_id(hdd_context_t *hdd_ctx,
6634 uint32_t request_id,
6635 uint8_t *pattern_id)
6636{
6637 uint32_t i;
6638
6639 mutex_lock(&hdd_ctx->op_ctx.op_lock);
6640 for (i = 0; i < MAXNUM_PERIODIC_TX_PTRNS; i++)
6641 {
6642 if (hdd_ctx->op_ctx.op_table[i].request_id == request_id)
6643 {
6644 hdd_ctx->op_ctx.op_table[i].request_id = 0;
6645 *pattern_id = hdd_ctx->op_ctx.op_table[i].pattern_id;
6646 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6647 return 0;
6648 }
6649 }
6650 mutex_unlock(&hdd_ctx->op_ctx.op_lock);
6651 return -EINVAL;
6652}
6653
6654
6655/*
6656 * define short names for the global vendor params
6657 * used by __wlan_hdd_cfg80211_offloaded_packets()
6658 */
6659#define PARAM_MAX QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_MAX
6660#define PARAM_REQUEST_ID \
6661 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_REQUEST_ID
6662#define PARAM_CONTROL \
6663 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SENDING_CONTROL
6664#define PARAM_IP_PACKET \
6665 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_IP_PACKET_DATA
6666#define PARAM_SRC_MAC_ADDR \
6667 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_SRC_MAC_ADDR
6668#define PARAM_DST_MAC_ADDR \
6669 QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_DST_MAC_ADDR
6670#define PARAM_PERIOD QCA_WLAN_VENDOR_ATTR_OFFLOADED_PACKETS_PERIOD
6671
6672/**
6673 * wlan_hdd_add_tx_ptrn() - add tx pattern
6674 * @adapter: adapter pointer
6675 * @hdd_ctx: hdd context
6676 * @tb: nl attributes
6677 *
6678 * This function reads the NL attributes and forms a AddTxPtrn message
6679 * posts it to SME.
6680 *
6681 */
6682static int
6683wlan_hdd_add_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6684 struct nlattr **tb)
6685{
6686 struct sSirAddPeriodicTxPtrn *add_req;
6687 eHalStatus status;
6688 uint32_t request_id, ret, len;
6689 uint8_t pattern_id = 0;
6690 v_MACADDR_t dst_addr;
6691 uint16_t eth_type = htons(ETH_P_IP);
6692
6693 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(adapter)))
6694 {
6695 hddLog(LOGE, FL("Not in Connected state!"));
6696 return -ENOTSUPP;
6697 }
6698
6699 add_req = vos_mem_malloc(sizeof(*add_req));
6700 if (!add_req)
6701 {
6702 hddLog(LOGE, FL("memory allocation failed"));
6703 return -ENOMEM;
6704 }
6705
6706 /* Parse and fetch request Id */
6707 if (!tb[PARAM_REQUEST_ID])
6708 {
6709 hddLog(LOGE, FL("attr request id failed"));
6710 goto fail;
6711 }
6712
6713 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6714 hddLog(LOG1, FL("Request Id: %u"), request_id);
6715 if (request_id == 0)
6716 {
6717 hddLog(LOGE, FL("request_id cannot be zero"));
6718 return -EINVAL;
6719 }
6720
6721 if (!tb[PARAM_PERIOD])
6722 {
6723 hddLog(LOGE, FL("attr period failed"));
6724 goto fail;
6725 }
6726 add_req->usPtrnIntervalMs = nla_get_u32(tb[PARAM_PERIOD]);
6727 hddLog(LOG1, FL("Period: %u ms"), add_req->usPtrnIntervalMs);
6728 if (add_req->usPtrnIntervalMs == 0)
6729 {
6730 hddLog(LOGE, FL("Invalid interval zero, return failure"));
6731 goto fail;
6732 }
6733
6734 if (!tb[PARAM_SRC_MAC_ADDR])
6735 {
6736 hddLog(LOGE, FL("attr source mac address failed"));
6737 goto fail;
6738 }
6739 nla_memcpy(add_req->macAddress, tb[PARAM_SRC_MAC_ADDR],
6740 VOS_MAC_ADDR_SIZE);
6741 hddLog(LOG1, "input src mac address: "MAC_ADDRESS_STR,
6742 MAC_ADDR_ARRAY(add_req->macAddress));
6743
6744 if (memcmp(add_req->macAddress, adapter->macAddressCurrent.bytes,
6745 VOS_MAC_ADDR_SIZE))
6746 {
6747 hddLog(LOGE,
6748 FL("input src mac address and connected ap bssid are different"));
6749 goto fail;
6750 }
6751
6752 if (!tb[PARAM_DST_MAC_ADDR])
6753 {
6754 hddLog(LOGE, FL("attr dst mac address failed"));
6755 goto fail;
6756 }
6757 nla_memcpy(dst_addr.bytes, tb[PARAM_DST_MAC_ADDR], VOS_MAC_ADDR_SIZE);
6758 hddLog(LOG1, "input dst mac address: "MAC_ADDRESS_STR,
6759 MAC_ADDR_ARRAY(dst_addr.bytes));
6760
6761 if (!tb[PARAM_IP_PACKET])
6762 {
6763 hddLog(LOGE, FL("attr ip packet failed"));
6764 goto fail;
6765 }
6766 add_req->ucPtrnSize = nla_len(tb[PARAM_IP_PACKET]);
6767 hddLog(LOG1, FL("IP packet len: %u"), add_req->ucPtrnSize);
6768
6769 if (add_req->ucPtrnSize < 0 ||
6770 add_req->ucPtrnSize > (PERIODIC_TX_PTRN_MAX_SIZE -
6771 HDD_ETH_HEADER_LEN))
6772 {
6773 hddLog(LOGE, FL("Invalid IP packet len: %d"),
6774 add_req->ucPtrnSize);
6775 goto fail;
6776 }
6777
6778 len = 0;
6779 vos_mem_copy(&add_req->ucPattern[0], dst_addr.bytes, VOS_MAC_ADDR_SIZE);
6780 len += VOS_MAC_ADDR_SIZE;
6781 vos_mem_copy(&add_req->ucPattern[len], add_req->macAddress,
6782 VOS_MAC_ADDR_SIZE);
6783 len += VOS_MAC_ADDR_SIZE;
6784 vos_mem_copy(&add_req->ucPattern[len], &eth_type, 2);
6785 len += 2;
6786
6787 /*
6788 * This is the IP packet, add 14 bytes Ethernet (802.3) header
6789 * ------------------------------------------------------------
6790 * | 14 bytes Ethernet (802.3) header | IP header and payload |
6791 * ------------------------------------------------------------
6792 */
6793 vos_mem_copy(&add_req->ucPattern[len],
6794 nla_data(tb[PARAM_IP_PACKET]),
6795 add_req->ucPtrnSize);
6796 add_req->ucPtrnSize += len;
6797
6798 VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
6799 add_req->ucPattern, add_req->ucPtrnSize);
6800
6801 ret = hdd_map_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6802 if (ret)
6803 {
6804 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6805 goto fail;
6806 }
6807 add_req->ucPtrnId = pattern_id;
6808 hddLog(LOG1, FL("pattern id: %d"), add_req->ucPtrnId);
6809
6810 status = sme_AddPeriodicTxPtrn(hdd_ctx->hHal, add_req);
6811 if (!HAL_STATUS_SUCCESS(status))
6812 {
6813 hddLog(LOGE,
6814 FL("sme_AddPeriodicTxPtrn failed (err=%d)"), status);
6815 goto fail;
6816 }
6817
6818 EXIT();
6819 vos_mem_free(add_req);
6820 return 0;
6821
6822fail:
6823 vos_mem_free(add_req);
6824 return -EINVAL;
6825}
6826
6827/**
6828 * wlan_hdd_del_tx_ptrn() - delete tx pattern
6829 * @adapter: adapter pointer
6830 * @hdd_ctx: hdd context
6831 * @tb: nl attributes
6832 *
6833 * This function reads the NL attributes and forms a DelTxPtrn message
6834 * posts it to SME.
6835 *
6836 */
6837static int
6838wlan_hdd_del_tx_ptrn(hdd_adapter_t *adapter, hdd_context_t *hdd_ctx,
6839 struct nlattr **tb)
6840{
6841 struct sSirDelPeriodicTxPtrn *del_req;
6842 eHalStatus status;
6843 uint32_t request_id, ret;
6844 uint8_t pattern_id = 0;
6845
6846 /* Parse and fetch request Id */
6847 if (!tb[PARAM_REQUEST_ID])
6848 {
6849 hddLog(LOGE, FL("attr request id failed"));
6850 return -EINVAL;
6851 }
6852 request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
6853 if (request_id == 0)
6854 {
6855 hddLog(LOGE, FL("request_id cannot be zero"));
6856 return -EINVAL;
6857 }
6858
6859 ret = hdd_unmap_req_id_to_pattern_id(hdd_ctx, request_id, &pattern_id);
6860 if (ret)
6861 {
6862 hddLog(LOGW, FL("req id to pattern id failed (ret=%d)"), ret);
6863 return -EINVAL;
6864 }
6865
6866 del_req = vos_mem_malloc(sizeof(*del_req));
6867 if (!del_req)
6868 {
6869 hddLog(LOGE, FL("memory allocation failed"));
6870 return -ENOMEM;
6871 }
6872
6873 vos_mem_set(del_req, sizeof(*del_req), 0);
6874 vos_mem_copy(del_req->macAddress, adapter->macAddressCurrent.bytes,
6875 VOS_MAC_ADDR_SIZE);
6876 hddLog(LOG1, MAC_ADDRESS_STR, MAC_ADDR_ARRAY(del_req->macAddress));
6877 del_req->ucPatternIdBitmap |= (0x1 << pattern_id);
6878 hddLog(LOG1, FL("Request Id: %u Pattern id: %d, bitmap %04x"),
6879 request_id, pattern_id, del_req->ucPatternIdBitmap);
6880
6881 status = sme_DelPeriodicTxPtrn(hdd_ctx->hHal, del_req);
6882 if (!HAL_STATUS_SUCCESS(status))
6883 {
6884 hddLog(LOGE,
6885 FL("sme_DelPeriodicTxPtrn failed (err=%d)"), status);
6886 goto fail;
6887 }
6888
6889 EXIT();
6890 vos_mem_free(del_req);
6891 return 0;
6892
6893fail:
6894 vos_mem_free(del_req);
6895 return -EINVAL;
6896}
6897
6898
6899/**
6900 * __wlan_hdd_cfg80211_offloaded_packets() - send offloaded packets
6901 * @wiphy: Pointer to wireless phy
6902 * @wdev: Pointer to wireless device
6903 * @data: Pointer to data
6904 * @data_len: Data length
6905 *
6906 * Return: 0 on success, negative errno on failure
6907 */
6908static int
6909__wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6910 struct wireless_dev *wdev,
6911 const void *data,
6912 int data_len)
6913{
6914 struct net_device *dev = wdev->netdev;
6915 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
6916 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6917 struct nlattr *tb[PARAM_MAX + 1];
6918 uint8_t control;
6919 int ret;
6920 static const struct nla_policy policy[PARAM_MAX + 1] =
6921 {
6922 [PARAM_REQUEST_ID] = { .type = NLA_U32 },
6923 [PARAM_CONTROL] = { .type = NLA_U32 },
6924 [PARAM_SRC_MAC_ADDR] = { .type = NLA_BINARY,
6925 .len = VOS_MAC_ADDR_SIZE },
6926 [PARAM_DST_MAC_ADDR] = { .type = NLA_BINARY,
6927 .len = VOS_MAC_ADDR_SIZE },
6928 [PARAM_PERIOD] = { .type = NLA_U32 },
6929 };
6930
6931 ENTER();
6932
6933 ret = wlan_hdd_validate_context(hdd_ctx);
6934 if (0 != ret)
6935 {
6936 hddLog(LOGE, FL("HDD context is not valid"));
6937 return ret;
6938 }
6939
6940 if (!sme_IsFeatureSupportedByFW(WLAN_PERIODIC_TX_PTRN))
6941 {
6942 hddLog(LOGE,
6943 FL("Periodic Tx Pattern Offload feature is not supported in FW!"));
6944 return -ENOTSUPP;
6945 }
6946
6947 if (nla_parse(tb, PARAM_MAX, data, data_len, policy))
6948 {
6949 hddLog(LOGE, FL("Invalid ATTR"));
6950 return -EINVAL;
6951 }
6952
6953 if (!tb[PARAM_CONTROL])
6954 {
6955 hddLog(LOGE, FL("attr control failed"));
6956 return -EINVAL;
6957 }
6958 control = nla_get_u32(tb[PARAM_CONTROL]);
6959 hddLog(LOG1, FL("Control: %d"), control);
6960
6961 if (control == WLAN_START_OFFLOADED_PACKETS)
6962 return wlan_hdd_add_tx_ptrn(adapter, hdd_ctx, tb);
6963 else if (control == WLAN_STOP_OFFLOADED_PACKETS)
6964 return wlan_hdd_del_tx_ptrn(adapter, hdd_ctx, tb);
6965 else
6966 {
6967 hddLog(LOGE, FL("Invalid control: %d"), control);
6968 return -EINVAL;
6969 }
6970}
6971
6972/*
6973 * done with short names for the global vendor params
6974 * used by __wlan_hdd_cfg80211_offloaded_packets()
6975 */
6976#undef PARAM_MAX
6977#undef PARAM_REQUEST_ID
6978#undef PARAM_CONTROL
6979#undef PARAM_IP_PACKET
6980#undef PARAM_SRC_MAC_ADDR
6981#undef PARAM_DST_MAC_ADDR
6982#undef PARAM_PERIOD
6983
6984/**
6985 * wlan_hdd_cfg80211_offloaded_packets() - Wrapper to offload packets
6986 * @wiphy: wiphy structure pointer
6987 * @wdev: Wireless device structure pointer
6988 * @data: Pointer to the data received
6989 * @data_len: Length of @data
6990 *
6991 * Return: 0 on success; errno on failure
6992 */
6993static int wlan_hdd_cfg80211_offloaded_packets(struct wiphy *wiphy,
6994 struct wireless_dev *wdev,
6995 const void *data,
6996 int data_len)
6997{
6998 int ret = 0;
6999
7000 vos_ssr_protect(__func__);
7001 ret = __wlan_hdd_cfg80211_offloaded_packets(wiphy,
7002 wdev, data, data_len);
7003 vos_ssr_unprotect(__func__);
7004
7005 return ret;
7006}
7007#endif
7008
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307009static const struct
7010nla_policy
7011qca_wlan_vendor_attr_policy[QCA_WLAN_VENDOR_ATTR_MAX+1] = {
7012 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
7013};
7014
7015/**
7016 * wlan_hdd_cfg80211_get_link_properties() - This function is used to
7017 * get link properties like nss, rate flags and operating frequency for
7018 * the connection with the given peer.
7019 * @wiphy: WIPHY structure pointer
7020 * @wdev: Wireless device structure pointer
7021 * @data: Pointer to the data received
7022 * @data_len: Length of the data received
7023 *
7024 * This function return the above link properties on success.
7025 *
7026 * Return: 0 on success and errno on failure
7027 */
7028static int wlan_hdd_cfg80211_get_link_properties(struct wiphy *wiphy,
7029 struct wireless_dev *wdev,
7030 const void *data,
7031 int data_len)
7032{
7033 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
7034 struct net_device *dev = wdev->netdev;
7035 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
7036 hdd_station_ctx_t *hdd_sta_ctx;
7037 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX+1];
7038 uint8_t peer_mac[VOS_MAC_ADDR_SIZE];
7039 uint32_t sta_id;
7040 struct sk_buff *reply_skb;
7041 uint32_t rate_flags = 0;
7042 uint8_t nss;
7043 uint8_t final_rate_flags = 0;
7044 uint32_t freq;
7045 v_CONTEXT_t pVosContext = NULL;
7046 ptSapContext pSapCtx = NULL;
7047
7048 if (0 != wlan_hdd_validate_context(hdd_ctx)) {
7049 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is not valid"));
7050 return -EINVAL;
7051 }
7052
7053 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
7054 qca_wlan_vendor_attr_policy)) {
7055 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid attribute"));
7056 return -EINVAL;
7057 }
7058
7059 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
7060 hddLog(VOS_TRACE_LEVEL_ERROR,
7061 FL("Attribute peerMac not provided for mode=%d"),
7062 adapter->device_mode);
7063 return -EINVAL;
7064 }
7065
7066 memcpy(peer_mac, nla_data(tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
7067 sizeof(peer_mac));
7068 hddLog(VOS_TRACE_LEVEL_INFO,
7069 FL("peerMac="MAC_ADDRESS_STR" for device_mode:%d"),
7070 MAC_ADDR_ARRAY(peer_mac), adapter->device_mode);
7071
7072 if (adapter->device_mode == WLAN_HDD_INFRA_STATION ||
7073 adapter->device_mode == WLAN_HDD_P2P_CLIENT) {
7074 hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
7075 if ((hdd_sta_ctx->conn_info.connState !=
7076 eConnectionState_Associated) ||
7077 !vos_mem_compare(hdd_sta_ctx->conn_info.bssId, peer_mac,
7078 VOS_MAC_ADDRESS_LEN)) {
7079 hddLog(VOS_TRACE_LEVEL_ERROR,
7080 FL("Not Associated to mac "MAC_ADDRESS_STR),
7081 MAC_ADDR_ARRAY(peer_mac));
7082 return -EINVAL;
7083 }
7084
7085 nss = 1; //pronto supports only one spatial stream
7086 freq = vos_chan_to_freq(
7087 hdd_sta_ctx->conn_info.operationChannel);
7088 rate_flags = hdd_sta_ctx->conn_info.rate_flags;
7089
7090 } else if (adapter->device_mode == WLAN_HDD_P2P_GO ||
7091 adapter->device_mode == WLAN_HDD_SOFTAP) {
7092
7093 pVosContext = ( WLAN_HDD_GET_CTX(adapter))->pvosContext;
7094 pSapCtx = VOS_GET_SAP_CB(pVosContext);
7095 if(pSapCtx == NULL){
7096 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7097 FL("psapCtx is NULL"));
7098 return -ENOENT;
7099 }
7100
7101
7102 for (sta_id = 0; sta_id < WLAN_MAX_STA_COUNT; sta_id++) {
7103 if (pSapCtx->aStaInfo[sta_id].isUsed &&
7104 !vos_is_macaddr_broadcast(
7105 &pSapCtx->aStaInfo[sta_id].macAddrSTA) &&
7106 vos_mem_compare(
7107 &pSapCtx->aStaInfo[sta_id].macAddrSTA,
7108 peer_mac, VOS_MAC_ADDRESS_LEN))
7109 break;
7110 }
7111
7112 if (WLAN_MAX_STA_COUNT == sta_id) {
7113 hddLog(VOS_TRACE_LEVEL_ERROR,
7114 FL("No active peer with mac="MAC_ADDRESS_STR),
7115 MAC_ADDR_ARRAY(peer_mac));
7116 return -EINVAL;
7117 }
7118
7119 nss = 1; //pronto supports only one spatial stream
7120 freq = vos_chan_to_freq(
7121 (WLAN_HDD_GET_AP_CTX_PTR(adapter))->operatingChannel);
7122 rate_flags = pSapCtx->aStaInfo[sta_id].rate_flags;
7123 } else {
7124 hddLog(VOS_TRACE_LEVEL_ERROR,
7125 FL("Not Associated! with mac"MAC_ADDRESS_STR),
7126 MAC_ADDR_ARRAY(peer_mac));
7127 return -EINVAL;
7128 }
7129
7130 if (!(rate_flags & eHAL_TX_RATE_LEGACY)) {
7131 if (rate_flags & eHAL_TX_RATE_VHT80) {
7132 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7133 final_rate_flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
7134 } else if (rate_flags & eHAL_TX_RATE_VHT40) {
7135 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7136 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7137 } else if (rate_flags & eHAL_TX_RATE_VHT20) {
7138 final_rate_flags |= RATE_INFO_FLAGS_VHT_MCS;
7139 } else if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40)) {
7140 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7141 if (rate_flags & eHAL_TX_RATE_HT40)
7142 final_rate_flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
7143 }
7144
7145 if (rate_flags & eHAL_TX_RATE_SGI) {
7146 if (!(final_rate_flags & RATE_INFO_FLAGS_VHT_MCS))
7147 final_rate_flags |= RATE_INFO_FLAGS_MCS;
7148 final_rate_flags |= RATE_INFO_FLAGS_SHORT_GI;
7149 }
7150 }
7151
7152 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
7153 sizeof(u8) + sizeof(u8) + sizeof(u32) + NLMSG_HDRLEN);
7154
7155 if (NULL == reply_skb) {
7156 hddLog(VOS_TRACE_LEVEL_ERROR,
7157 FL("getLinkProperties: skb alloc failed"));
7158 return -EINVAL;
7159 }
7160
7161 if (nla_put_u8(reply_skb,
7162 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_NSS,
7163 nss) ||
7164 nla_put_u8(reply_skb,
7165 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_RATE_FLAGS,
7166 final_rate_flags) ||
7167 nla_put_u32(reply_skb,
7168 QCA_WLAN_VENDOR_ATTR_LINK_PROPERTIES_FREQ,
7169 freq)) {
7170 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed"));
7171 kfree_skb(reply_skb);
7172 return -EINVAL;
7173 }
7174
7175 return cfg80211_vendor_cmd_reply(reply_skb);
7176}
7177
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307178#define PARAM_WIFICONFIG_MAX QCA_WLAN_VENDOR_ATTR_CONFIG_MAX
7179#define PARAM_MODULATED_DTIM QCA_WLAN_VENDOR_ATTR_CONFIG_MODULATED_DTIM
7180#define PARAM_STATS_AVG_FACTOR QCA_WLAN_VENDOR_ATTR_CONFIG_STATS_AVG_FACTOR
7181#define PARAM_GUARD_TIME QCA_WLAN_VENDOR_ATTR_CONFIG_GUARD_TIME
7182
7183/**
7184 * __wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7185 * vendor command
7186 *
7187 * @wiphy: wiphy device pointer
7188 * @wdev: wireless device pointer
7189 * @data: Vendor command data buffer
7190 * @data_len: Buffer length
7191 *
7192 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7193 *
7194 * Return: EOK or other error codes.
7195 */
7196
7197static int __wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7198 struct wireless_dev *wdev,
7199 const void *data,
7200 int data_len)
7201{
7202 struct net_device *dev = wdev->netdev;
7203 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7204 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7205 hdd_station_ctx_t *pHddStaCtx;
7206 struct nlattr *tb[PARAM_WIFICONFIG_MAX + 1];
7207 tpSetWifiConfigParams pReq;
7208 eHalStatus status;
7209 int ret_val;
7210 static const struct nla_policy policy[PARAM_WIFICONFIG_MAX + 1] = {
7211 [PARAM_STATS_AVG_FACTOR] = { .type = NLA_U16 },
7212 [PARAM_MODULATED_DTIM] = { .type = NLA_U32 },
7213 [PARAM_GUARD_TIME] = { .type = NLA_U32},
7214 };
7215
7216 ENTER();
7217
7218 if (VOS_FTM_MODE == hdd_get_conparam()) {
7219 hddLog(LOGE, FL("Command not allowed in FTM mode"));
7220 return -EINVAL;
7221 }
7222
7223 ret_val = wlan_hdd_validate_context(pHddCtx);
7224 if (ret_val) {
7225 return ret_val;
7226 }
7227
7228 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7229
7230 if (!hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) {
7231 hddLog(LOGE, FL("Not in Connected state!"));
7232 return -ENOTSUPP;
7233 }
7234
7235 if (nla_parse(tb, PARAM_WIFICONFIG_MAX, data, data_len, policy)) {
7236 hddLog(LOGE, FL("Invalid ATTR"));
7237 return -EINVAL;
7238 }
7239
7240 /* check the Wifi Capability */
7241 if ( (TRUE != pHddCtx->cfg_ini->fEnableWifiConfig) &&
7242 (TRUE != sme_IsFeatureSupportedByFW(WIFI_CONFIG)))
7243 {
7244 hddLog(VOS_TRACE_LEVEL_ERROR,
7245 FL("WIFICONFIG not supported by Firmware"));
7246 return -EINVAL;
7247 }
7248
7249 pReq = vos_mem_malloc(sizeof(tSetWifiConfigParams));
7250
7251 if (!pReq) {
7252 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
7253 "%s: Not able to allocate memory for tSetWifiConfigParams",
7254 __func__);
7255 return eHAL_STATUS_E_MALLOC_FAILED;
7256 }
7257
7258 vos_mem_set(pReq, sizeof(tSetWifiConfigParams), 0);
7259
7260 pReq->sessionId = pAdapter->sessionId;
7261 vos_mem_copy( &pReq->bssId, pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
7262
7263 if (tb[PARAM_MODULATED_DTIM]) {
7264 pReq->paramValue = nla_get_u32(
7265 tb[PARAM_MODULATED_DTIM]);
7266 hddLog(LOG1, FL("Modulated DTIM: pReq->paramValue:%d "),
7267 pReq->paramValue);
7268 pHddCtx->cfg_ini->fMaxLIModulatedDTIM = pReq->paramValue;
7269 hdd_set_pwrparams(pHddCtx);
7270 if (BMPS == pmcGetPmcState(pHddCtx->hHal)) {
7271 hddLog( LOG1, FL("WifiConfig: Requesting FullPower!"));
7272
7273 sme_RequestFullPower(WLAN_HDD_GET_HAL_CTX(pAdapter),
7274 iw_full_power_cbfn, pAdapter,
7275 eSME_FULL_PWR_NEEDED_BY_HDD);
7276 }
7277 else
7278 {
7279 hddLog( LOG1, FL("WifiConfig Not in BMPS state"));
7280 }
7281 }
7282
7283 if (tb[PARAM_STATS_AVG_FACTOR]) {
7284 pReq->paramType = WIFI_CONFIG_SET_AVG_STATS_FACTOR;
7285 pReq->paramValue = nla_get_u16(
7286 tb[PARAM_STATS_AVG_FACTOR]);
7287 hddLog(LOG1, FL("AVG_STATS_FACTOR pReq->paramType:%d,pReq->paramValue:%d "),
7288 pReq->paramType, pReq->paramValue);
7289 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7290
7291 if (eHAL_STATUS_SUCCESS != status)
7292 {
7293 vos_mem_free(pReq);
7294 pReq = NULL;
7295 ret_val = -EPERM;
7296 return ret_val;
7297 }
7298 }
7299
7300
7301 if (tb[PARAM_GUARD_TIME]) {
7302 pReq->paramType = WIFI_CONFIG_SET_GUARD_TIME;
7303 pReq->paramValue = nla_get_u32(
7304 tb[PARAM_GUARD_TIME]);
7305 hddLog(LOG1, FL("GUARD_TIME pReq->paramType:%d,pReq->paramValue:%d "),
7306 pReq->paramType, pReq->paramValue);
7307 status = sme_set_wificonfig_params(pHddCtx->hHal, pReq);
7308
7309 if (eHAL_STATUS_SUCCESS != status)
7310 {
7311 vos_mem_free(pReq);
7312 pReq = NULL;
7313 ret_val = -EPERM;
7314 return ret_val;
7315 }
7316
7317 }
7318
7319 EXIT();
7320 return ret_val;
7321}
7322
7323/**
7324 * wlan_hdd_cfg80211_wifi_configuration_set() - Wifi configuration
7325 * vendor command
7326 *
7327 * @wiphy: wiphy device pointer
7328 * @wdev: wireless device pointer
7329 * @data: Vendor command data buffer
7330 * @data_len: Buffer length
7331 *
7332 * Handles QCA_WLAN_VENDOR_ATTR_CONFIG_MAX.
7333 *
7334 * Return: EOK or other error codes.
7335 */
7336static int wlan_hdd_cfg80211_wifi_configuration_set(struct wiphy *wiphy,
7337 struct wireless_dev *wdev,
7338 const void *data,
7339 int data_len)
7340{
7341 int ret;
7342
7343 vos_ssr_protect(__func__);
7344 ret = __wlan_hdd_cfg80211_wifi_configuration_set(wiphy, wdev,
7345 data, data_len);
7346 vos_ssr_unprotect(__func__);
7347
7348 return ret;
7349}
Sunil Duttc69bccb2014-05-26 21:30:20 +05307350const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
7351{
Mukul Sharma2a271632014-10-13 14:59:01 +05307352 {
7353 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7354 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
7355 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7356 WIPHY_VENDOR_CMD_NEED_NETDEV |
7357 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307358 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05307359 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05307360
7361 {
7362 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7363 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
7364 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7365 WIPHY_VENDOR_CMD_NEED_NETDEV |
7366 WIPHY_VENDOR_CMD_NEED_RUNNING,
7367 .doit = wlan_hdd_cfg80211_nan_request
7368 },
7369
Sunil Duttc69bccb2014-05-26 21:30:20 +05307370#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7371 {
7372 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7373 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
7374 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7375 WIPHY_VENDOR_CMD_NEED_NETDEV |
7376 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307377 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05307378 },
7379
7380 {
7381 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7382 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
7383 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7384 WIPHY_VENDOR_CMD_NEED_NETDEV |
7385 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307386 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05307387 },
7388
7389 {
7390 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7391 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
7392 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7393 WIPHY_VENDOR_CMD_NEED_NETDEV |
7394 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307395 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05307396 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307397#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307398#ifdef WLAN_FEATURE_EXTSCAN
7399 {
7400 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7401 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
7402 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7403 WIPHY_VENDOR_CMD_NEED_NETDEV |
7404 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307405 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05307406 },
7407 {
7408 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7409 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
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_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05307414 },
7415 {
7416 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7417 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
7418 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7419 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307420 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05307421 },
7422 {
7423 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7424 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
7425 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7426 WIPHY_VENDOR_CMD_NEED_NETDEV |
7427 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307428 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05307429 },
7430 {
7431 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7432 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
7433 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7434 WIPHY_VENDOR_CMD_NEED_NETDEV |
7435 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307436 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05307437 },
7438 {
7439 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7440 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
7441 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7442 WIPHY_VENDOR_CMD_NEED_NETDEV |
7443 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307444 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307445 },
7446 {
7447 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7448 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
7449 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7450 WIPHY_VENDOR_CMD_NEED_NETDEV |
7451 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307452 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05307453 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307454 {
7455 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7456 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
7457 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7458 WIPHY_VENDOR_CMD_NEED_NETDEV |
7459 WIPHY_VENDOR_CMD_NEED_RUNNING,
7460 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
7461 },
7462 {
7463 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7464 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
7465 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7466 WIPHY_VENDOR_CMD_NEED_NETDEV |
7467 WIPHY_VENDOR_CMD_NEED_RUNNING,
7468 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
7469 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307470#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307471/*EXT TDLS*/
7472 {
7473 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7474 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
7475 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7476 WIPHY_VENDOR_CMD_NEED_NETDEV |
7477 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307478 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05307479 },
7480 {
7481 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7482 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
7483 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7484 WIPHY_VENDOR_CMD_NEED_NETDEV |
7485 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307486 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05307487 },
7488 {
7489 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7490 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
7491 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7492 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307493 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05307494 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05307495 {
7496 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7497 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
7498 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7499 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307500 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05307501 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05307502 {
7503 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7504 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
7505 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7506 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307507 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05307508 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307509 {
7510 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7511 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
7512 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7513 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307514 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05307515 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307516 {
7517 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7518 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
7519 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7520 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05307521 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05307522 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307523 {
7524 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05307525 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
7526 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7527 WIPHY_VENDOR_CMD_NEED_NETDEV |
7528 WIPHY_VENDOR_CMD_NEED_RUNNING,
7529 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
7530 },
7531 {
7532 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05307533 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
7534 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7535 WIPHY_VENDOR_CMD_NEED_NETDEV |
7536 WIPHY_VENDOR_CMD_NEED_RUNNING,
7537 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05307538 },
7539 {
7540 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7541 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
7542 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7543 WIPHY_VENDOR_CMD_NEED_NETDEV,
7544 .doit = wlan_hdd_cfg80211_wifi_logger_start
7545 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05307546 {
7547 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7548 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
7549 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7550 WIPHY_VENDOR_CMD_NEED_NETDEV|
7551 WIPHY_VENDOR_CMD_NEED_RUNNING,
7552 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05307553 },
7554 {
7555 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7556 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
7557 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7558 WIPHY_VENDOR_CMD_NEED_NETDEV |
7559 WIPHY_VENDOR_CMD_NEED_RUNNING,
7560 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307561 },
7562 {
7563 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7564 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI,
7565 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7566 WIPHY_VENDOR_CMD_NEED_NETDEV |
7567 WIPHY_VENDOR_CMD_NEED_RUNNING,
7568 .doit = wlan_hdd_cfg80211_monitor_rssi
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307569 },
7570#ifdef WLAN_FEATURE_OFFLOAD_PACKETS
7571 {
7572 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7573 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_OFFLOADED_PACKETS,
7574 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7575 WIPHY_VENDOR_CMD_NEED_NETDEV |
7576 WIPHY_VENDOR_CMD_NEED_RUNNING,
7577 .doit = wlan_hdd_cfg80211_offloaded_packets
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307578 },
Srinivas Girigowda8bf64cb2015-09-30 19:50:09 +05307579#endif
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307580 {
7581 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7582 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES,
7583 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7584 WIPHY_VENDOR_CMD_NEED_NETDEV |
7585 WIPHY_VENDOR_CMD_NEED_RUNNING,
7586 .doit = wlan_hdd_cfg80211_get_link_properties
Arun Khandavalli7eeb1592015-10-19 21:36:57 +05307587 },
7588 {
7589 .info.vendor_id = QCA_NL80211_VENDOR_ID,
7590 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION,
7591 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
7592 WIPHY_VENDOR_CMD_NEED_NETDEV |
7593 WIPHY_VENDOR_CMD_NEED_RUNNING,
7594 .doit = wlan_hdd_cfg80211_wifi_configuration_set
Deepthi Gowriae6a1662015-10-12 12:59:37 +05307595 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05307596};
7597
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007598/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05307599static const
7600struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007601{
7602#ifdef FEATURE_WLAN_CH_AVOID
7603 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05307604 .vendor_id = QCA_NL80211_VENDOR_ID,
7605 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007606 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05307607#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
7608#ifdef WLAN_FEATURE_LINK_LAYER_STATS
7609 {
7610 /* Index = 1*/
7611 .vendor_id = QCA_NL80211_VENDOR_ID,
7612 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
7613 },
7614 {
7615 /* Index = 2*/
7616 .vendor_id = QCA_NL80211_VENDOR_ID,
7617 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
7618 },
7619 {
7620 /* Index = 3*/
7621 .vendor_id = QCA_NL80211_VENDOR_ID,
7622 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
7623 },
7624 {
7625 /* Index = 4*/
7626 .vendor_id = QCA_NL80211_VENDOR_ID,
7627 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
7628 },
7629 {
7630 /* Index = 5*/
7631 .vendor_id = QCA_NL80211_VENDOR_ID,
7632 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
7633 },
7634 {
7635 /* Index = 6*/
7636 .vendor_id = QCA_NL80211_VENDOR_ID,
7637 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
7638 },
7639#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05307640#ifdef WLAN_FEATURE_EXTSCAN
7641 {
7642 .vendor_id = QCA_NL80211_VENDOR_ID,
7643 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
7644 },
7645 {
7646 .vendor_id = QCA_NL80211_VENDOR_ID,
7647 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
7648 },
7649 {
7650 .vendor_id = QCA_NL80211_VENDOR_ID,
7651 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
7652 },
7653 {
7654 .vendor_id = QCA_NL80211_VENDOR_ID,
7655 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
7656 },
7657 {
7658 .vendor_id = QCA_NL80211_VENDOR_ID,
7659 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
7660 },
7661 {
7662 .vendor_id = QCA_NL80211_VENDOR_ID,
7663 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
7664 },
7665 {
7666 .vendor_id = QCA_NL80211_VENDOR_ID,
7667 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
7668 },
7669 {
7670 .vendor_id = QCA_NL80211_VENDOR_ID,
7671 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
7672 },
7673 {
7674 .vendor_id = QCA_NL80211_VENDOR_ID,
7675 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
7676 },
7677 {
7678 .vendor_id = QCA_NL80211_VENDOR_ID,
7679 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
7680 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05307681 {
7682 .vendor_id = QCA_NL80211_VENDOR_ID,
7683 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
7684 },
7685 {
7686 .vendor_id = QCA_NL80211_VENDOR_ID,
7687 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
7688 },
7689 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
7690 .vendor_id = QCA_NL80211_VENDOR_ID,
7691 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
7692 },
7693 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
7694 .vendor_id = QCA_NL80211_VENDOR_ID,
7695 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
7696 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05307697#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05307698/*EXT TDLS*/
7699 {
7700 .vendor_id = QCA_NL80211_VENDOR_ID,
7701 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
7702 },
c_manjeecfd1efb2015-09-25 19:32:34 +05307703 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
7704 .vendor_id = QCA_NL80211_VENDOR_ID,
7705 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
7706 },
7707
Srinivas Dasari030bad32015-02-18 23:23:54 +05307708
7709 {
7710 .vendor_id = QCA_NL80211_VENDOR_ID,
7711 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
7712 },
7713
Sushant Kaushik084f6592015-09-10 13:11:56 +05307714 {
7715 .vendor_id = QCA_NL80211_VENDOR_ID,
7716 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
Gupta, Kapil7c34b322015-09-30 13:12:35 +05307717 },
7718 [QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI_INDEX] = {
7719 .vendor_id = QCA_NL80211_VENDOR_ID,
7720 .subcmd = QCA_NL80211_VENDOR_SUBCMD_MONITOR_RSSI
7721 },
Sushant Kaushik084f6592015-09-10 13:11:56 +05307722
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08007723};
7724
Jeff Johnson295189b2012-06-20 16:38:30 -07007725/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307726 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307727 * This function is called by hdd_wlan_startup()
7728 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307729 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07007730 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307731struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07007732{
7733 struct wiphy *wiphy;
7734 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307735 /*
7736 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07007737 */
7738 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
7739
7740 if (!wiphy)
7741 {
7742 /* Print error and jump into err label and free the memory */
7743 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
7744 return NULL;
7745 }
7746
Sunil Duttc69bccb2014-05-26 21:30:20 +05307747
Jeff Johnson295189b2012-06-20 16:38:30 -07007748 return wiphy;
7749}
7750
7751/*
7752 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307753 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07007754 * private ioctl to change the band value
7755 */
7756int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
7757{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307758 int i, j;
7759 eNVChannelEnabledType channelEnabledState;
7760
Jeff Johnsone7245742012-09-05 17:12:55 -07007761 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307762
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307763 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007764 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307765
7766 if (NULL == wiphy->bands[i])
7767 {
7768 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
7769 __func__, i);
7770 continue;
7771 }
7772
7773 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
7774 {
7775 struct ieee80211_supported_band *band = wiphy->bands[i];
7776
7777 channelEnabledState = vos_nv_getChannelEnabledState(
7778 band->channels[j].hw_value);
7779
7780 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
7781 {
Abhishek Singh678227a2014-11-04 10:52:38 +05307782 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307783 continue;
7784 }
7785 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
7786 {
7787 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7788 continue;
7789 }
7790
7791 if (NV_CHANNEL_DISABLE == channelEnabledState ||
7792 NV_CHANNEL_INVALID == channelEnabledState)
7793 {
7794 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7795 }
7796 else if (NV_CHANNEL_DFS == channelEnabledState)
7797 {
7798 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
7799 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
7800 }
7801 else
7802 {
7803 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
7804 |IEEE80211_CHAN_RADAR);
7805 }
7806 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007807 }
7808 return 0;
7809}
7810/*
7811 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307812 * This function is called by hdd_wlan_startup()
7813 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07007814 * This function is used to initialize and register wiphy structure.
7815 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05307816int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007817 struct wiphy *wiphy,
7818 hdd_config_t *pCfg
7819 )
7820{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307821 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307822 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
7823
Jeff Johnsone7245742012-09-05 17:12:55 -07007824 ENTER();
7825
Jeff Johnson295189b2012-06-20 16:38:30 -07007826 /* Now bind the underlying wlan device with wiphy */
7827 set_wiphy_dev(wiphy, dev);
7828
7829 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007830
Kiet Lam6c583332013-10-14 05:37:09 +05307831#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07007832 /* the flag for the other case would be initialzed in
7833 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07007834 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05307835#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007836
Amar Singhalfddc28c2013-09-05 13:03:40 -07007837 /* This will disable updating of NL channels from passive to
7838 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307839#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7840 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
7841#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07007842 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307843#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07007844
Amar Singhala49cbc52013-10-08 18:37:44 -07007845
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007846#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07007847 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
7848 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
7849 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07007850 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05307851#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
7852 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
7853#else
7854 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
7855#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007856#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07007857
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007858#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007859 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08007860#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007861 || pCfg->isFastRoamIniFeatureEnabled
7862#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08007863#ifdef FEATURE_WLAN_ESE
7864 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07007865#endif
7866 )
7867 {
7868 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
7869 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08007870#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007871#ifdef FEATURE_WLAN_TDLS
7872 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
7873 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
7874#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307875#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05307876 if (pCfg->configPNOScanSupport)
7877 {
7878 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
7879 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
7880 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
7881 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
7882 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05307883#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08007884
Abhishek Singh10d85972015-04-17 10:27:23 +05307885#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7886 wiphy->features |= NL80211_FEATURE_HT_IBSS;
7887#endif
7888
Amar Singhalfddc28c2013-09-05 13:03:40 -07007889#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007890 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
7891 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07007892 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07007893 driver need to determine what to do with both
7894 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07007895
7896 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07007897#else
7898 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07007899#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007900
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307901 wiphy->max_scan_ssids = MAX_SCAN_SSID;
7902
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05307903 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07007904
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307905 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
7906
Jeff Johnson295189b2012-06-20 16:38:30 -07007907 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05307908 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
7909 | BIT(NL80211_IFTYPE_ADHOC)
7910 | BIT(NL80211_IFTYPE_P2P_CLIENT)
7911 | BIT(NL80211_IFTYPE_P2P_GO)
7912 | BIT(NL80211_IFTYPE_AP);
7913
7914 if (VOS_MONITOR_MODE == hdd_get_conparam())
7915 {
7916 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
7917 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007918
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307919 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007920 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307921#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
7922 if( pCfg->enableMCC )
7923 {
7924 /* Currently, supports up to two channels */
7925 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007926
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307927 if( !pCfg->allowMCCGODiffBI )
7928 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007929
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307930 }
7931 wiphy->iface_combinations = &wlan_hdd_iface_combination;
7932 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007933#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05307934 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08007935
Jeff Johnson295189b2012-06-20 16:38:30 -07007936 /* Before registering we need to update the ht capabilitied based
7937 * on ini values*/
7938 if( !pCfg->ShortGI20MhzEnable )
7939 {
7940 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
7941 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
7942 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
7943 }
7944
7945 if( !pCfg->ShortGI40MhzEnable )
7946 {
7947 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
7948 }
7949
7950 if( !pCfg->nChannelBondingMode5GHz )
7951 {
7952 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
7953 }
7954
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307955 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05307956 if (true == hdd_is_5g_supported(pHddCtx))
7957 {
7958 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
7959 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307960
7961 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
7962 {
7963
7964 if (NULL == wiphy->bands[i])
7965 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05307966 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05307967 __func__, i);
7968 continue;
7969 }
7970
7971 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
7972 {
7973 struct ieee80211_supported_band *band = wiphy->bands[i];
7974
7975 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
7976 {
7977 // Enable social channels for P2P
7978 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
7979 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
7980 else
7981 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7982 continue;
7983 }
7984 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
7985 {
7986 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
7987 continue;
7988 }
7989 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007990 }
7991 /*Initialise the supported cipher suite details*/
7992 wiphy->cipher_suites = hdd_cipher_suites;
7993 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
7994
7995 /*signal strength in mBm (100*dBm) */
7996 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
7997
7998#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05307999 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07008000#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008001
Sunil Duttc69bccb2014-05-26 21:30:20 +05308002 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
8003 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08008004 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
8005 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
8006
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308007 EXIT();
8008 return 0;
8009}
8010
8011/* In this function we are registering wiphy. */
8012int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
8013{
8014 ENTER();
8015 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008016 if (0 > wiphy_register(wiphy))
8017 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308018 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07008019 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
8020 return -EIO;
8021 }
8022
8023 EXIT();
8024 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308025}
Jeff Johnson295189b2012-06-20 16:38:30 -07008026
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308027/* In this function we are updating channel list when,
8028 regulatory domain is FCC and country code is US.
8029 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
8030 As per FCC smart phone is not a indoor device.
8031 GO should not opeate on indoor channels */
8032void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
8033{
8034 int j;
8035 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
8036 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
8037 //Default counrtycode from NV at the time of wiphy initialization.
8038 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
8039 &defaultCountryCode[0]))
8040 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008041 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308042 }
8043 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
8044 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05308045 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
8046 {
8047 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
8048 return;
8049 }
8050 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
8051 {
8052 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
8053 // Mark UNII -1 band channel as passive
8054 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
8055 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
8056 }
8057 }
8058}
8059
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308060/* This function registers for all frame which supplicant is interested in */
8061void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008062{
Jeff Johnson295189b2012-06-20 16:38:30 -07008063 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8064 /* Register for all P2P action, public action etc frames */
8065 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8066
Jeff Johnsone7245742012-09-05 17:12:55 -07008067 ENTER();
8068
Jeff Johnson295189b2012-06-20 16:38:30 -07008069 /* Right now we are registering these frame when driver is getting
8070 initialized. Once we will move to 2.6.37 kernel, in which we have
8071 frame register ops, we will move this code as a part of that */
8072 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308073 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07008074 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8075
8076 /* GAS Initial Response */
8077 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8078 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308079
Jeff Johnson295189b2012-06-20 16:38:30 -07008080 /* GAS Comeback Request */
8081 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8082 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8083
8084 /* GAS Comeback Response */
8085 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8086 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8087
8088 /* P2P Public Action */
8089 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308090 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008091 P2P_PUBLIC_ACTION_FRAME_SIZE );
8092
8093 /* P2P Action */
8094 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8095 (v_U8_t*)P2P_ACTION_FRAME,
8096 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07008097
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05308098 /* WNM BSS Transition Request frame */
8099 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8100 (v_U8_t*)WNM_BSS_ACTION_FRAME,
8101 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008102
8103 /* WNM-Notification */
8104 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
8105 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8106 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008107}
8108
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05308109void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07008110{
Jeff Johnson295189b2012-06-20 16:38:30 -07008111 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
8112 /* Register for all P2P action, public action etc frames */
8113 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
8114
Jeff Johnsone7245742012-09-05 17:12:55 -07008115 ENTER();
8116
Jeff Johnson295189b2012-06-20 16:38:30 -07008117 /* Right now we are registering these frame when driver is getting
8118 initialized. Once we will move to 2.6.37 kernel, in which we have
8119 frame register ops, we will move this code as a part of that */
8120 /* GAS Initial Request */
8121
8122 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8123 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
8124
8125 /* GAS Initial Response */
8126 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8127 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308128
Jeff Johnson295189b2012-06-20 16:38:30 -07008129 /* GAS Comeback Request */
8130 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8131 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
8132
8133 /* GAS Comeback Response */
8134 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8135 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
8136
8137 /* P2P Public Action */
8138 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308139 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07008140 P2P_PUBLIC_ACTION_FRAME_SIZE );
8141
8142 /* P2P Action */
8143 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8144 (v_U8_t*)P2P_ACTION_FRAME,
8145 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07008146 /* WNM-Notification */
8147 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
8148 (v_U8_t*)WNM_NOTIFICATION_FRAME,
8149 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07008150}
8151
8152#ifdef FEATURE_WLAN_WAPI
8153void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05308154 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07008155{
8156 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8157 tCsrRoamSetKey setKey;
8158 v_BOOL_t isConnected = TRUE;
8159 int status = 0;
8160 v_U32_t roamId= 0xFF;
8161 tANI_U8 *pKeyPtr = NULL;
8162 int n = 0;
8163
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308164 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
8165 __func__, hdd_device_modetoString(pAdapter->device_mode),
8166 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008167
Gopichand Nakkalae7480202013-02-11 15:24:22 +05308168 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008169 setKey.keyId = key_index; // Store Key ID
8170 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
8171 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
8172 setKey.paeRole = 0 ; // the PAE role
8173 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
8174 {
8175 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
8176 }
8177 else
8178 {
8179 isConnected = hdd_connIsConnected(pHddStaCtx);
8180 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
8181 }
8182 setKey.keyLength = key_Len;
8183 pKeyPtr = setKey.Key;
8184 memcpy( pKeyPtr, key, key_Len);
8185
Arif Hussain6d2a3322013-11-17 19:50:10 -08008186 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07008187 __func__, key_Len);
8188 for (n = 0 ; n < key_Len; n++)
8189 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
8190 __func__,n,setKey.Key[n]);
8191
8192 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
8193 if ( isConnected )
8194 {
8195 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
8196 pAdapter->sessionId, &setKey, &roamId );
8197 }
8198 if ( status != 0 )
8199 {
8200 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8201 "[%4d] sme_RoamSetKey returned ERROR status= %d",
8202 __LINE__, status );
8203 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
8204 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05308205 /* Need to clear any trace of key value in the memory.
8206 * Thus zero out the memory even though it is local
8207 * variable.
8208 */
8209 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07008210}
8211#endif /* FEATURE_WLAN_WAPI*/
8212
8213#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308214int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07008215 beacon_data_t **ppBeacon,
8216 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008217#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308218int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008219 beacon_data_t **ppBeacon,
8220 struct cfg80211_beacon_data *params,
8221 int dtim_period)
8222#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308223{
Jeff Johnson295189b2012-06-20 16:38:30 -07008224 int size;
8225 beacon_data_t *beacon = NULL;
8226 beacon_data_t *old = NULL;
8227 int head_len,tail_len;
8228
Jeff Johnsone7245742012-09-05 17:12:55 -07008229 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07008230 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308231 {
8232 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8233 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008234 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308235 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008236
8237 old = pAdapter->sessionCtx.ap.beacon;
8238
8239 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308240 {
8241 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8242 FL("session(%d) old and new heads points to NULL"),
8243 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008244 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308245 }
8246
8247 if (params->tail && !params->tail_len)
8248 {
8249 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8250 FL("tail_len is zero but tail is not NULL"));
8251 return -EINVAL;
8252 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008253
Jeff Johnson295189b2012-06-20 16:38:30 -07008254#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
8255 /* Kernel 3.0 is not updating dtim_period for set beacon */
8256 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308257 {
8258 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8259 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008260 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308261 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008262#endif
8263
8264 if(params->head)
8265 head_len = params->head_len;
8266 else
8267 head_len = old->head_len;
8268
8269 if(params->tail || !old)
8270 tail_len = params->tail_len;
8271 else
8272 tail_len = old->tail_len;
8273
8274 size = sizeof(beacon_data_t) + head_len + tail_len;
8275
8276 beacon = kzalloc(size, GFP_KERNEL);
8277
8278 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308279 {
8280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8281 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008282 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308283 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008284
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008285#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008286 if(params->dtim_period || !old )
8287 beacon->dtim_period = params->dtim_period;
8288 else
8289 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008290#else
8291 if(dtim_period || !old )
8292 beacon->dtim_period = dtim_period;
8293 else
8294 beacon->dtim_period = old->dtim_period;
8295#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308296
Jeff Johnson295189b2012-06-20 16:38:30 -07008297 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
8298 beacon->tail = beacon->head + head_len;
8299 beacon->head_len = head_len;
8300 beacon->tail_len = tail_len;
8301
8302 if(params->head) {
8303 memcpy (beacon->head,params->head,beacon->head_len);
8304 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308305 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07008306 if(old)
8307 memcpy (beacon->head,old->head,beacon->head_len);
8308 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308309
Jeff Johnson295189b2012-06-20 16:38:30 -07008310 if(params->tail) {
8311 memcpy (beacon->tail,params->tail,beacon->tail_len);
8312 }
8313 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308314 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07008315 memcpy (beacon->tail,old->tail,beacon->tail_len);
8316 }
8317
8318 *ppBeacon = beacon;
8319
8320 kfree(old);
8321
8322 return 0;
8323
8324}
Jeff Johnson295189b2012-06-20 16:38:30 -07008325
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308326v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
8327#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
8328 const v_U8_t *pIes,
8329#else
8330 v_U8_t *pIes,
8331#endif
8332 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008333{
8334 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308335 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07008336 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308337
Jeff Johnson295189b2012-06-20 16:38:30 -07008338 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308339 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008340 elem_id = ptr[0];
8341 elem_len = ptr[1];
8342 left -= 2;
8343 if(elem_len > left)
8344 {
8345 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008346 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008347 eid,elem_len,left);
8348 return NULL;
8349 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308350 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07008351 {
8352 return ptr;
8353 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308354
Jeff Johnson295189b2012-06-20 16:38:30 -07008355 left -= elem_len;
8356 ptr += (elem_len + 2);
8357 }
8358 return NULL;
8359}
8360
Jeff Johnson295189b2012-06-20 16:38:30 -07008361/* Check if rate is 11g rate or not */
8362static int wlan_hdd_rate_is_11g(u8 rate)
8363{
Sanjay Devnani28322e22013-06-21 16:13:40 -07008364 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07008365 u8 i;
8366 for (i = 0; i < 8; i++)
8367 {
8368 if(rate == gRateArray[i])
8369 return TRUE;
8370 }
8371 return FALSE;
8372}
8373
8374/* Check for 11g rate and set proper 11g only mode */
8375static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
8376 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
8377{
8378 u8 i, num_rates = pIe[0];
8379
8380 pIe += 1;
8381 for ( i = 0; i < num_rates; i++)
8382 {
8383 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
8384 {
8385 /* If rate set have 11g rate than change the mode to 11G */
8386 *pSapHw_mode = eSAP_DOT11_MODE_11g;
8387 if (pIe[i] & BASIC_RATE_MASK)
8388 {
8389 /* If we have 11g rate as basic rate, it means mode
8390 is 11g only mode.
8391 */
8392 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
8393 *pCheckRatesfor11g = FALSE;
8394 }
8395 }
8396 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
8397 {
8398 *require_ht = TRUE;
8399 }
8400 }
8401 return;
8402}
8403
8404static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
8405{
8406 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
8407 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8408 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
8409 u8 checkRatesfor11g = TRUE;
8410 u8 require_ht = FALSE;
8411 u8 *pIe=NULL;
8412
8413 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
8414
8415 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
8416 pBeacon->head_len, WLAN_EID_SUPP_RATES);
8417 if (pIe != NULL)
8418 {
8419 pIe += 1;
8420 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8421 &pConfig->SapHw_mode);
8422 }
8423
8424 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8425 WLAN_EID_EXT_SUPP_RATES);
8426 if (pIe != NULL)
8427 {
8428
8429 pIe += 1;
8430 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
8431 &pConfig->SapHw_mode);
8432 }
8433
8434 if( pConfig->channel > 14 )
8435 {
8436 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
8437 }
8438
8439 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
8440 WLAN_EID_HT_CAPABILITY);
8441
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308442 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07008443 {
8444 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
8445 if(require_ht)
8446 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
8447 }
8448}
8449
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308450static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
8451 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
8452{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008453 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308454 v_U8_t *pIe = NULL;
8455 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8456
8457 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
8458 pBeacon->tail, pBeacon->tail_len);
8459
8460 if (pIe)
8461 {
8462 ielen = pIe[1] + 2;
8463 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8464 {
8465 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
8466 }
8467 else
8468 {
8469 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
8470 return -EINVAL;
8471 }
8472 *total_ielen += ielen;
8473 }
8474 return 0;
8475}
8476
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008477static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
8478 v_U8_t *genie, v_U8_t *total_ielen)
8479{
8480 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
8481 int left = pBeacon->tail_len;
8482 v_U8_t *ptr = pBeacon->tail;
8483 v_U8_t elem_id, elem_len;
8484 v_U16_t ielen = 0;
8485
8486 if ( NULL == ptr || 0 == left )
8487 return;
8488
8489 while (left >= 2)
8490 {
8491 elem_id = ptr[0];
8492 elem_len = ptr[1];
8493 left -= 2;
8494 if (elem_len > left)
8495 {
8496 hddLog( VOS_TRACE_LEVEL_ERROR,
8497 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
8498 elem_id, elem_len, left);
8499 return;
8500 }
8501 if (IE_EID_VENDOR == elem_id)
8502 {
8503 /* skipping the VSIE's which we don't want to include or
8504 * it will be included by existing code
8505 */
8506 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
8507#ifdef WLAN_FEATURE_WFD
8508 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
8509#endif
8510 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8511 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8512 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
8513 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
8514 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
8515 {
8516 ielen = ptr[1] + 2;
8517 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
8518 {
8519 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
8520 *total_ielen += ielen;
8521 }
8522 else
8523 {
8524 hddLog( VOS_TRACE_LEVEL_ERROR,
8525 "IE Length is too big "
8526 "IEs eid=%d elem_len=%d total_ie_lent=%d",
8527 elem_id, elem_len, *total_ielen);
8528 }
8529 }
8530 }
8531
8532 left -= elem_len;
8533 ptr += (elem_len + 2);
8534 }
8535 return;
8536}
8537
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008538#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008539static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8540 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008541#else
8542static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
8543 struct cfg80211_beacon_data *params)
8544#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008545{
8546 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308547 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008548 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07008549 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008550
8551 genie = vos_mem_malloc(MAX_GENIE_LEN);
8552
8553 if(genie == NULL) {
8554
8555 return -ENOMEM;
8556 }
8557
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308558 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8559 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008560 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308561 hddLog(LOGE,
8562 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308563 ret = -EINVAL;
8564 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008565 }
8566
8567#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308568 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8569 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
8570 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308571 hddLog(LOGE,
8572 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308573 ret = -EINVAL;
8574 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008575 }
8576#endif
8577
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308578 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
8579 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07008580 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308581 hddLog(LOGE,
8582 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308583 ret = -EINVAL;
8584 goto done;
8585 }
8586
8587 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
8588 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07008589 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07008590 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008591
8592 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8593 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
8594 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
8595 {
8596 hddLog(LOGE,
8597 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008598 ret = -EINVAL;
8599 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008600 }
8601
8602 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8603 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
8604 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8605 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8606 ==eHAL_STATUS_FAILURE)
8607 {
8608 hddLog(LOGE,
8609 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008610 ret = -EINVAL;
8611 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008612 }
8613
8614 // Added for ProResp IE
8615 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
8616 {
8617 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
8618 u8 probe_rsp_ie_len[3] = {0};
8619 u8 counter = 0;
8620 /* Check Probe Resp Length if it is greater then 255 then Store
8621 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
8622 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
8623 Store More then 255 bytes into One Variable.
8624 */
8625 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
8626 {
8627 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
8628 {
8629 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
8630 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
8631 }
8632 else
8633 {
8634 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
8635 rem_probe_resp_ie_len = 0;
8636 }
8637 }
8638
8639 rem_probe_resp_ie_len = 0;
8640
8641 if (probe_rsp_ie_len[0] > 0)
8642 {
8643 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8644 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
8645 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8646 probe_rsp_ie_len[0], NULL,
8647 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8648 {
8649 hddLog(LOGE,
8650 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008651 ret = -EINVAL;
8652 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008653 }
8654 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
8655 }
8656
8657 if (probe_rsp_ie_len[1] > 0)
8658 {
8659 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8660 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
8661 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8662 probe_rsp_ie_len[1], NULL,
8663 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8664 {
8665 hddLog(LOGE,
8666 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008667 ret = -EINVAL;
8668 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008669 }
8670 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
8671 }
8672
8673 if (probe_rsp_ie_len[2] > 0)
8674 {
8675 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8676 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
8677 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
8678 probe_rsp_ie_len[2], NULL,
8679 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8680 {
8681 hddLog(LOGE,
8682 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008683 ret = -EINVAL;
8684 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008685 }
8686 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
8687 }
8688
8689 if (probe_rsp_ie_len[1] == 0 )
8690 {
8691 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8692 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
8693 eANI_BOOLEAN_FALSE) )
8694 {
8695 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008696 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008697 }
8698 }
8699
8700 if (probe_rsp_ie_len[2] == 0 )
8701 {
8702 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8703 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
8704 eANI_BOOLEAN_FALSE) )
8705 {
8706 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008707 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008708 }
8709 }
8710
8711 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8712 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
8713 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
8714 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
8715 == eHAL_STATUS_FAILURE)
8716 {
8717 hddLog(LOGE,
8718 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008719 ret = -EINVAL;
8720 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008721 }
8722 }
8723 else
8724 {
8725 // Reset WNI_CFG_PROBE_RSP Flags
8726 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
8727
8728 hddLog(VOS_TRACE_LEVEL_INFO,
8729 "%s: No Probe Response IE received in set beacon",
8730 __func__);
8731 }
8732
8733 // Added for AssocResp IE
8734 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
8735 {
8736 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8737 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
8738 params->assocresp_ies_len, NULL,
8739 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
8740 {
8741 hddLog(LOGE,
8742 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07008743 ret = -EINVAL;
8744 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07008745 }
8746
8747 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8748 WNI_CFG_ASSOC_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_ASSOC_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 hddLog(VOS_TRACE_LEVEL_INFO,
8762 "%s: No Assoc Response IE received in set beacon",
8763 __func__);
8764
8765 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
8766 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8767 eANI_BOOLEAN_FALSE) )
8768 {
8769 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008770 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008771 }
8772 }
8773
Jeff Johnsone7245742012-09-05 17:12:55 -07008774done:
Jeff Johnson295189b2012-06-20 16:38:30 -07008775 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05308776 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008777}
Jeff Johnson295189b2012-06-20 16:38:30 -07008778
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308779/*
Jeff Johnson295189b2012-06-20 16:38:30 -07008780 * FUNCTION: wlan_hdd_validate_operation_channel
8781 * called by wlan_hdd_cfg80211_start_bss() and
8782 * wlan_hdd_cfg80211_set_channel()
8783 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308784 * channel list.
8785 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07008786VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008787{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308788
Jeff Johnson295189b2012-06-20 16:38:30 -07008789 v_U32_t num_ch = 0;
8790 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
8791 u32 indx = 0;
8792 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308793 v_U8_t fValidChannel = FALSE, count = 0;
8794 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308795
Jeff Johnson295189b2012-06-20 16:38:30 -07008796 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8797
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308798 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07008799 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308800 /* Validate the channel */
8801 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07008802 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308803 if ( channel == rfChannels[count].channelNum )
8804 {
8805 fValidChannel = TRUE;
8806 break;
8807 }
8808 }
8809 if (fValidChannel != TRUE)
8810 {
8811 hddLog(VOS_TRACE_LEVEL_ERROR,
8812 "%s: Invalid Channel [%d]", __func__, channel);
8813 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07008814 }
8815 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308816 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008817 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05308818 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
8819 valid_ch, &num_ch))
8820 {
8821 hddLog(VOS_TRACE_LEVEL_ERROR,
8822 "%s: failed to get valid channel list", __func__);
8823 return VOS_STATUS_E_FAILURE;
8824 }
8825 for (indx = 0; indx < num_ch; indx++)
8826 {
8827 if (channel == valid_ch[indx])
8828 {
8829 break;
8830 }
8831 }
8832
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308833 if (indx >= num_ch)
8834 {
8835 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
8836 {
8837 eCsrBand band;
8838 unsigned int freq;
8839
8840 sme_GetFreqBand(hHal, &band);
8841
8842 if (eCSR_BAND_5G == band)
8843 {
8844#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
8845 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
8846 {
8847 freq = ieee80211_channel_to_frequency(channel,
8848 IEEE80211_BAND_2GHZ);
8849 }
8850 else
8851 {
8852 freq = ieee80211_channel_to_frequency(channel,
8853 IEEE80211_BAND_5GHZ);
8854 }
8855#else
8856 freq = ieee80211_channel_to_frequency(channel);
8857#endif
8858 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
8859 return VOS_STATUS_SUCCESS;
8860 }
8861 }
8862
8863 hddLog(VOS_TRACE_LEVEL_ERROR,
8864 "%s: Invalid Channel [%d]", __func__, channel);
8865 return VOS_STATUS_E_FAILURE;
8866 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008867 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05308868
Jeff Johnson295189b2012-06-20 16:38:30 -07008869 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308870
Jeff Johnson295189b2012-06-20 16:38:30 -07008871}
8872
Viral Modi3a32cc52013-02-08 11:14:52 -08008873/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308874 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08008875 * This function is used to set the channel number
8876 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308877static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08008878 struct ieee80211_channel *chan,
8879 enum nl80211_channel_type channel_type
8880 )
8881{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308882 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08008883 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07008884 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08008885 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308886 hdd_context_t *pHddCtx;
8887 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08008888
8889 ENTER();
8890
8891 if( NULL == dev )
8892 {
8893 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008894 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08008895 return -ENODEV;
8896 }
8897 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308898
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308899 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8900 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
8901 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08008902 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308903 "%s: device_mode = %s (%d) freq = %d", __func__,
8904 hdd_device_modetoString(pAdapter->device_mode),
8905 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308906
8907 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8908 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308909 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08008910 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308911 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08008912 }
8913
8914 /*
8915 * Do freq to chan conversion
8916 * TODO: for 11a
8917 */
8918
8919 channel = ieee80211_frequency_to_channel(freq);
8920
8921 /* Check freq range */
8922 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
8923 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
8924 {
8925 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008926 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08008927 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
8928 WNI_CFG_CURRENT_CHANNEL_STAMAX);
8929 return -EINVAL;
8930 }
8931
8932 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
8933
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05308934 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
8935 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08008936 {
8937 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
8938 {
8939 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008940 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08008941 return -EINVAL;
8942 }
8943 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8944 "%s: set channel to [%d] for device mode =%d",
8945 __func__, channel,pAdapter->device_mode);
8946 }
8947 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08008948 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08008949 )
8950 {
8951 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
8952 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
8953 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8954
8955 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
8956 {
8957 /* Link is up then return cant set channel*/
8958 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008959 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08008960 return -EINVAL;
8961 }
8962
8963 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
8964 pHddStaCtx->conn_info.operationChannel = channel;
8965 pRoamProfile->ChannelInfo.ChannelList =
8966 &pHddStaCtx->conn_info.operationChannel;
8967 }
8968 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08008969 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08008970 )
8971 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05308972 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
8973 {
8974 if(VOS_STATUS_SUCCESS !=
8975 wlan_hdd_validate_operation_channel(pAdapter,channel))
8976 {
8977 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008978 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05308979 return -EINVAL;
8980 }
8981 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
8982 }
8983 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08008984 {
8985 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
8986
8987 /* If auto channel selection is configured as enable/ 1 then ignore
8988 channel set by supplicant
8989 */
8990 if ( cfg_param->apAutoChannelSelection )
8991 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05308992 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
8993 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08008994 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308995 "%s: set channel to auto channel (0) for device mode =%s (%d)",
8996 __func__, hdd_device_modetoString(pAdapter->device_mode),
8997 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08008998 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05308999 else
9000 {
9001 if(VOS_STATUS_SUCCESS !=
9002 wlan_hdd_validate_operation_channel(pAdapter,channel))
9003 {
9004 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009005 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05309006 return -EINVAL;
9007 }
9008 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
9009 }
Viral Modi3a32cc52013-02-08 11:14:52 -08009010 }
9011 }
9012 else
9013 {
9014 hddLog(VOS_TRACE_LEVEL_FATAL,
9015 "%s: Invalid device mode failed to set valid channel", __func__);
9016 return -EINVAL;
9017 }
9018 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309019 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08009020}
9021
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309022static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
9023 struct net_device *dev,
9024 struct ieee80211_channel *chan,
9025 enum nl80211_channel_type channel_type
9026 )
9027{
9028 int ret;
9029
9030 vos_ssr_protect(__func__);
9031 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
9032 vos_ssr_unprotect(__func__);
9033
9034 return ret;
9035}
9036
Jeff Johnson295189b2012-06-20 16:38:30 -07009037#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9038static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9039 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009040#else
9041static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
9042 struct cfg80211_beacon_data *params,
9043 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309044 enum nl80211_hidden_ssid hidden_ssid,
9045 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009046#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009047{
9048 tsap_Config_t *pConfig;
9049 beacon_data_t *pBeacon = NULL;
9050 struct ieee80211_mgmt *pMgmt_frame;
9051 v_U8_t *pIe=NULL;
9052 v_U16_t capab_info;
9053 eCsrAuthType RSNAuthType;
9054 eCsrEncryptionType RSNEncryptType;
9055 eCsrEncryptionType mcRSNEncryptType;
9056 int status = VOS_STATUS_SUCCESS;
9057 tpWLAN_SAPEventCB pSapEventCallback;
9058 hdd_hostapd_state_t *pHostapdState;
9059 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
9060 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309061 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009062 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309063 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07009064 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08009065 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05309066 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07009067 v_BOOL_t MFPCapable = VOS_FALSE;
9068 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309069 v_BOOL_t sapEnable11AC =
9070 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07009071 ENTER();
9072
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309073 iniConfig = pHddCtx->cfg_ini;
9074
Jeff Johnson295189b2012-06-20 16:38:30 -07009075 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
9076
9077 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
9078
9079 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
9080
9081 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
9082
9083 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
9084
9085 //channel is already set in the set_channel Call back
9086 //pConfig->channel = pCommitConfig->channel;
9087
9088 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309089 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07009090 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
9091
9092 pConfig->dtim_period = pBeacon->dtim_period;
9093
Arif Hussain6d2a3322013-11-17 19:50:10 -08009094 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07009095 pConfig->dtim_period);
9096
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08009097 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07009098 {
9099 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009100 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05309101 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
9102 {
9103 tANI_BOOLEAN restartNeeded;
9104 pConfig->ieee80211d = 1;
9105 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
9106 sme_setRegInfo(hHal, pConfig->countryCode);
9107 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
9108 }
9109 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07009110 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07009111 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07009112 pConfig->ieee80211d = 1;
9113 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
9114 sme_setRegInfo(hHal, pConfig->countryCode);
9115 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07009116 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009117 else
9118 {
9119 pConfig->ieee80211d = 0;
9120 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309121 /*
9122 * If auto channel is configured i.e. channel is 0,
9123 * so skip channel validation.
9124 */
9125 if( AUTO_CHANNEL_SELECT != pConfig->channel )
9126 {
9127 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
9128 {
9129 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009130 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05309131 return -EINVAL;
9132 }
9133 }
9134 else
9135 {
9136 if(1 != pHddCtx->is_dynamic_channel_range_set)
9137 {
9138 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
9139 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
9140 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
9141 }
9142 pHddCtx->is_dynamic_channel_range_set = 0;
9143 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009144 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07009145 else
Jeff Johnson295189b2012-06-20 16:38:30 -07009146 {
9147 pConfig->ieee80211d = 0;
9148 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309149
9150#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9151 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9152 pConfig->authType = eSAP_OPEN_SYSTEM;
9153 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9154 pConfig->authType = eSAP_SHARED_KEY;
9155 else
9156 pConfig->authType = eSAP_AUTO_SWITCH;
9157#else
9158 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
9159 pConfig->authType = eSAP_OPEN_SYSTEM;
9160 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
9161 pConfig->authType = eSAP_SHARED_KEY;
9162 else
9163 pConfig->authType = eSAP_AUTO_SWITCH;
9164#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009165
9166 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309167
9168 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07009169 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
9170
9171 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
9172
9173 /*Set wps station to configured*/
9174 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
9175
9176 if(pIe)
9177 {
9178 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
9179 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009180 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07009181 return -EINVAL;
9182 }
9183 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
9184 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07009185 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07009186 /* Check 15 bit of WPS IE as it contain information for wps state
9187 * WPS state
9188 */
9189 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
9190 {
9191 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
9192 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
9193 {
9194 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
9195 }
9196 }
9197 }
9198 else
9199 {
9200 pConfig->wps_state = SAP_WPS_DISABLED;
9201 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309202 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07009203
c_hpothufe599e92014-06-16 11:38:55 +05309204 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9205 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
9206 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
9207 eCSR_ENCRYPT_TYPE_NONE;
9208
Jeff Johnson295189b2012-06-20 16:38:30 -07009209 pConfig->RSNWPAReqIELength = 0;
9210 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309211 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07009212 WLAN_EID_RSN);
9213 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309214 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009215 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9216 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9217 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309218 /* The actual processing may eventually be more extensive than
9219 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07009220 * by the app.
9221 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309222 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009223 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9224 &RSNEncryptType,
9225 &mcRSNEncryptType,
9226 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009227 &MFPCapable,
9228 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009229 pConfig->pRSNWPAReqIE[1]+2,
9230 pConfig->pRSNWPAReqIE );
9231
9232 if( VOS_STATUS_SUCCESS == status )
9233 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309234 /* Now copy over all the security attributes you have
9235 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009236 * */
9237 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9238 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9239 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9240 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309241 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009242 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009243 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9244 }
9245 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309246
Jeff Johnson295189b2012-06-20 16:38:30 -07009247 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9248 pBeacon->tail, pBeacon->tail_len);
9249
9250 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
9251 {
9252 if (pConfig->pRSNWPAReqIE)
9253 {
9254 /*Mixed mode WPA/WPA2*/
9255 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
9256 pConfig->RSNWPAReqIELength += pIe[1] + 2;
9257 }
9258 else
9259 {
9260 pConfig->RSNWPAReqIELength = pIe[1] + 2;
9261 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
9262 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309263 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07009264 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
9265 &RSNEncryptType,
9266 &mcRSNEncryptType,
9267 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08009268 &MFPCapable,
9269 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07009270 pConfig->pRSNWPAReqIE[1]+2,
9271 pConfig->pRSNWPAReqIE );
9272
9273 if( VOS_STATUS_SUCCESS == status )
9274 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309275 /* Now copy over all the security attributes you have
9276 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07009277 * */
9278 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
9279 pConfig->mcRSNEncryptType = mcRSNEncryptType;
9280 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
9281 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05309282 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08009283 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07009284 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
9285 }
9286 }
9287 }
9288
Jeff Johnson4416a782013-03-25 14:17:50 -07009289 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
9290 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
9291 return -EINVAL;
9292 }
9293
Jeff Johnson295189b2012-06-20 16:38:30 -07009294 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
9295
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009296#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009297 if (params->ssid != NULL)
9298 {
9299 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
9300 pConfig->SSIDinfo.ssid.length = params->ssid_len;
9301 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9302 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9303 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009304#else
9305 if (ssid != NULL)
9306 {
9307 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
9308 pConfig->SSIDinfo.ssid.length = ssid_len;
9309 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
9310 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
9311 }
9312#endif
9313
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309314 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07009315 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309316
Jeff Johnson295189b2012-06-20 16:38:30 -07009317 /* default value */
9318 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
9319 pConfig->num_accept_mac = 0;
9320 pConfig->num_deny_mac = 0;
9321
9322 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9323 pBeacon->tail, pBeacon->tail_len);
9324
9325 /* pIe for black list is following form:
9326 type : 1 byte
9327 length : 1 byte
9328 OUI : 4 bytes
9329 acl type : 1 byte
9330 no of mac addr in black list: 1 byte
9331 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309332 */
9333 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009334 {
9335 pConfig->SapMacaddr_acl = pIe[6];
9336 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009337 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009338 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309339 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
9340 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009341 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9342 for (i = 0; i < pConfig->num_deny_mac; i++)
9343 {
9344 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9345 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309346 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009347 }
9348 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
9349 pBeacon->tail, pBeacon->tail_len);
9350
9351 /* pIe for white list is following form:
9352 type : 1 byte
9353 length : 1 byte
9354 OUI : 4 bytes
9355 acl type : 1 byte
9356 no of mac addr in white list: 1 byte
9357 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309358 */
9359 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07009360 {
9361 pConfig->SapMacaddr_acl = pIe[6];
9362 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08009363 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009364 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309365 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
9366 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009367 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
9368 for (i = 0; i < pConfig->num_accept_mac; i++)
9369 {
9370 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
9371 acl_entry++;
9372 }
9373 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05309374
Jeff Johnson295189b2012-06-20 16:38:30 -07009375 wlan_hdd_set_sapHwmode(pHostapdAdapter);
9376
Jeff Johnsone7245742012-09-05 17:12:55 -07009377#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009378 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309379 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
9380 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05309381 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
9382 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08009383 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
9384 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05309385 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
9386 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07009387 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309388 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07009389 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309390 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009391
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309392 /* If ACS disable and selected channel <= 14
9393 * OR
9394 * ACS enabled and ACS operating band is choosen as 2.4
9395 * AND
9396 * VHT in 2.4G Disabled
9397 * THEN
9398 * Fallback to 11N mode
9399 */
9400 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
9401 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05309402 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05309403 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009404 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05309405 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
9406 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07009407 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
9408 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009409 }
9410#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309411
Jeff Johnson295189b2012-06-20 16:38:30 -07009412 // ht_capab is not what the name conveys,this is used for protection bitmap
9413 pConfig->ht_capab =
9414 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
9415
9416 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
9417 {
9418 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
9419 return -EINVAL;
9420 }
9421
9422 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309423 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07009424 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
9425 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309426 pConfig->obssProtEnabled =
9427 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07009428
Chet Lanctot8cecea22014-02-11 19:09:36 -08009429#ifdef WLAN_FEATURE_11W
9430 pConfig->mfpCapable = MFPCapable;
9431 pConfig->mfpRequired = MFPRequired;
9432 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
9433 pConfig->mfpCapable, pConfig->mfpRequired);
9434#endif
9435
Arif Hussain6d2a3322013-11-17 19:50:10 -08009436 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07009437 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08009438 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
9439 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
9440 (int)pConfig->channel);
9441 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
9442 pConfig->SapHw_mode, pConfig->privacy,
9443 pConfig->authType);
9444 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
9445 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
9446 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
9447 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07009448
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309449 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07009450 {
9451 //Bss already started. just return.
9452 //TODO Probably it should update some beacon params.
9453 hddLog( LOGE, "Bss Already started...Ignore the request");
9454 EXIT();
9455 return 0;
9456 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309457
Agarwal Ashish51325b52014-06-16 16:50:49 +05309458 if (vos_max_concurrent_connections_reached()) {
9459 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9460 return -EINVAL;
9461 }
9462
Jeff Johnson295189b2012-06-20 16:38:30 -07009463 pConfig->persona = pHostapdAdapter->device_mode;
9464
Peng Xu2446a892014-09-05 17:21:18 +05309465 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
9466 if ( NULL != psmeConfig)
9467 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309468 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05309469 sme_GetConfigParam(hHal, psmeConfig);
9470 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05309471#ifdef WLAN_FEATURE_AP_HT40_24G
9472 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
9473 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
9474 && pHddCtx->cfg_ini->apHT40_24GEnabled)
9475 {
9476 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
9477 sme_UpdateConfig (hHal, psmeConfig);
9478 }
9479#endif
Peng Xu2446a892014-09-05 17:21:18 +05309480 vos_mem_free(psmeConfig);
9481 }
Peng Xuafc34e32014-09-25 13:23:55 +05309482 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05309483
Jeff Johnson295189b2012-06-20 16:38:30 -07009484 pSapEventCallback = hdd_hostapd_SAPEventCB;
9485 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
9486 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
9487 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009488 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009489 return -EINVAL;
9490 }
9491
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309492 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07009493 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
9494
9495 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309496
Jeff Johnson295189b2012-06-20 16:38:30 -07009497 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309498 {
9499 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009500 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07009501 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07009502 VOS_ASSERT(0);
9503 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309504
Jeff Johnson295189b2012-06-20 16:38:30 -07009505 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05309506 /* Initialize WMM configuation */
9507 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309508 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009509
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009510#ifdef WLAN_FEATURE_P2P_DEBUG
9511 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
9512 {
9513 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
9514 {
9515 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9516 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009517 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009518 }
9519 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
9520 {
9521 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
9522 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08009523 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009524 }
9525 }
9526#endif
9527
Jeff Johnson295189b2012-06-20 16:38:30 -07009528 pHostapdState->bCommit = TRUE;
9529 EXIT();
9530
9531 return 0;
9532}
9533
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009534#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309535static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309536 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07009537 struct beacon_parameters *params)
9538{
9539 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309540 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309541 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009542
9543 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309544
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309545 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9546 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
9547 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309548 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
9549 hdd_device_modetoString(pAdapter->device_mode),
9550 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009551
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309552 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9553 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309554 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009555 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309556 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009557 }
9558
Agarwal Ashish51325b52014-06-16 16:50:49 +05309559 if (vos_max_concurrent_connections_reached()) {
9560 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9561 return -EINVAL;
9562 }
9563
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309564 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009565 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009566 )
9567 {
9568 beacon_data_t *old,*new;
9569
9570 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309571
Jeff Johnson295189b2012-06-20 16:38:30 -07009572 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309573 {
9574 hddLog(VOS_TRACE_LEVEL_WARN,
9575 FL("already beacon info added to session(%d)"),
9576 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009577 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309578 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009579
9580 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9581
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309582 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07009583 {
9584 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009585 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009586 return -EINVAL;
9587 }
9588
9589 pAdapter->sessionCtx.ap.beacon = new;
9590
9591 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9592 }
9593
9594 EXIT();
9595 return status;
9596}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309597
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309598static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
9599 struct net_device *dev,
9600 struct beacon_parameters *params)
9601{
9602 int ret;
9603
9604 vos_ssr_protect(__func__);
9605 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
9606 vos_ssr_unprotect(__func__);
9607
9608 return ret;
9609}
9610
9611static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009612 struct net_device *dev,
9613 struct beacon_parameters *params)
9614{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309615 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309616 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9617 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309618 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009619
9620 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309621
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309622 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9623 TRACE_CODE_HDD_CFG80211_SET_BEACON,
9624 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
9625 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9626 __func__, hdd_device_modetoString(pAdapter->device_mode),
9627 pAdapter->device_mode);
9628
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309629 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9630 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309631 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009632 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309633 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009634 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309635
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309636 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009637 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309638 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009639 {
9640 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309641
Jeff Johnson295189b2012-06-20 16:38:30 -07009642 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309643
Jeff Johnson295189b2012-06-20 16:38:30 -07009644 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309645 {
9646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9647 FL("session(%d) old and new heads points to NULL"),
9648 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009649 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309650 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009651
9652 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
9653
9654 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309655 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009656 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009657 return -EINVAL;
9658 }
9659
9660 pAdapter->sessionCtx.ap.beacon = new;
9661
9662 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
9663 }
9664
9665 EXIT();
9666 return status;
9667}
9668
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309669static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
9670 struct net_device *dev,
9671 struct beacon_parameters *params)
9672{
9673 int ret;
9674
9675 vos_ssr_protect(__func__);
9676 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
9677 vos_ssr_unprotect(__func__);
9678
9679 return ret;
9680}
9681
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009682#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9683
9684#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309685static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009686 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009687#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309688static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009689 struct net_device *dev)
9690#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009691{
9692 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07009693 hdd_context_t *pHddCtx = NULL;
9694 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309695 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309696 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009697
9698 ENTER();
9699
9700 if (NULL == pAdapter)
9701 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309702 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07009703 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009704 return -ENODEV;
9705 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009706
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309707 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9708 TRACE_CODE_HDD_CFG80211_STOP_AP,
9709 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309710 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9711 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309712 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009713 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309714 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07009715 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009716
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07009717 pScanInfo = &pHddCtx->scan_info;
9718
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309719 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9720 __func__, hdd_device_modetoString(pAdapter->device_mode),
9721 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009722
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309723 ret = wlan_hdd_scan_abort(pAdapter);
9724
Girish Gowli4bf7a632014-06-12 13:42:11 +05309725 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07009726 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9728 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309729
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309730 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07009731 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9733 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08009734
Jeff Johnsone7245742012-09-05 17:12:55 -07009735 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309736 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07009737 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05309738 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07009739 }
9740
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05309741 /* Delete all associated STAs before stopping AP/P2P GO */
9742 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05309743 hdd_hostapd_stop(dev);
9744
Jeff Johnson295189b2012-06-20 16:38:30 -07009745 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009746 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009747 )
9748 {
9749 beacon_data_t *old;
9750
9751 old = pAdapter->sessionCtx.ap.beacon;
9752
9753 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309754 {
9755 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9756 FL("session(%d) beacon data points to NULL"),
9757 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07009758 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309759 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009760
Jeff Johnson295189b2012-06-20 16:38:30 -07009761 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009762
9763 mutex_lock(&pHddCtx->sap_lock);
9764 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
9765 {
Jeff Johnson4416a782013-03-25 14:17:50 -07009766 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009767 {
9768 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9769
9770 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
9771
9772 if (!VOS_IS_STATUS_SUCCESS(status))
9773 {
9774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009775 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07009776 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309777 }
9778 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009779 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05309780 /* BSS stopped, clear the active sessions for this device mode */
9781 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009782 }
9783 mutex_unlock(&pHddCtx->sap_lock);
9784
9785 if(status != VOS_STATUS_SUCCESS)
9786 {
9787 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009788 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009789 return -EINVAL;
9790 }
9791
Jeff Johnson4416a782013-03-25 14:17:50 -07009792 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009793 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
9794 ==eHAL_STATUS_FAILURE)
9795 {
9796 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009797 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009798 }
9799
Jeff Johnson4416a782013-03-25 14:17:50 -07009800 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07009801 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
9802 eANI_BOOLEAN_FALSE) )
9803 {
9804 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009805 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07009806 }
9807
9808 // Reset WNI_CFG_PROBE_RSP Flags
9809 wlan_hdd_reset_prob_rspies(pAdapter);
9810
9811 pAdapter->sessionCtx.ap.beacon = NULL;
9812 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07009813#ifdef WLAN_FEATURE_P2P_DEBUG
9814 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
9815 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
9816 {
9817 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
9818 "GO got removed");
9819 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
9820 }
9821#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009822 }
9823 EXIT();
9824 return status;
9825}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009826
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309827#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9828static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
9829 struct net_device *dev)
9830{
9831 int ret;
9832
9833 vos_ssr_protect(__func__);
9834 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
9835 vos_ssr_unprotect(__func__);
9836
9837 return ret;
9838}
9839#else
9840static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
9841 struct net_device *dev)
9842{
9843 int ret;
9844
9845 vos_ssr_protect(__func__);
9846 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
9847 vos_ssr_unprotect(__func__);
9848
9849 return ret;
9850}
9851#endif
9852
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009853#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
9854
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309855static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309856 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009857 struct cfg80211_ap_settings *params)
9858{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309859 hdd_adapter_t *pAdapter;
9860 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309861 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009862
9863 ENTER();
9864
Girish Gowlib143d7a2015-02-18 19:39:55 +05309865 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07009866 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05309868 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309869 return -ENODEV;
9870 }
9871
9872 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9873 if (NULL == pAdapter)
9874 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309875 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309876 "%s: HDD adapter is Null", __func__);
9877 return -ENODEV;
9878 }
9879
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309880 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9881 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
9882 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309883 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
9884 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309885 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309886 "%s: HDD adapter magic is invalid", __func__);
9887 return -ENODEV;
9888 }
9889
9890 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309891 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309892 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309893 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309894 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309895 }
9896
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309897 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
9898 __func__, hdd_device_modetoString(pAdapter->device_mode),
9899 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309900
9901 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009902 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009903 )
9904 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309905 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009906
9907 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309908
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009909 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309910 {
9911 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
9912 FL("already beacon info added to session(%d)"),
9913 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009914 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309915 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009916
Girish Gowlib143d7a2015-02-18 19:39:55 +05309917#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
9918 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
9919 &new,
9920 &params->beacon);
9921#else
9922 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
9923 &new,
9924 &params->beacon,
9925 params->dtim_period);
9926#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009927
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309928 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009929 {
9930 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05309931 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009932 return -EINVAL;
9933 }
9934 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08009935#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07009936 wlan_hdd_cfg80211_set_channel(wiphy, dev,
9937#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
9938 params->channel, params->channel_type);
9939#else
9940 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
9941#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08009942#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009943 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05309944 params->ssid_len, params->hidden_ssid,
9945 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009946 }
9947
9948 EXIT();
9949 return status;
9950}
9951
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309952static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
9953 struct net_device *dev,
9954 struct cfg80211_ap_settings *params)
9955{
9956 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009957
Mukul Sharmab0e0a982014-12-15 18:58:53 +05309958 vos_ssr_protect(__func__);
9959 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
9960 vos_ssr_unprotect(__func__);
9961
9962 return ret;
9963}
9964
9965static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009966 struct net_device *dev,
9967 struct cfg80211_beacon_data *params)
9968{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309969 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309970 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309971 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009972
9973 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309974
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309975 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9976 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
9977 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08009978 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009979 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309980
9981 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9982 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309983 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07009984 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309985 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07009986 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009987
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309988 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009989 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309990 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009991 {
9992 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309993
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009994 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309995
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009996 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309997 {
9998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9999 FL("session(%d) beacon data points to NULL"),
10000 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010001 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010002 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010003
10004 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
10005
10006 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010007 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010008 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010009 return -EINVAL;
10010 }
10011
10012 pAdapter->sessionCtx.ap.beacon = new;
10013
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +053010014 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
10015 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010016 }
10017
10018 EXIT();
10019 return status;
10020}
10021
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010022static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
10023 struct net_device *dev,
10024 struct cfg80211_beacon_data *params)
10025{
10026 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010027
Mukul Sharmab0e0a982014-12-15 18:58:53 +053010028 vos_ssr_protect(__func__);
10029 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
10030 vos_ssr_unprotect(__func__);
10031
10032 return ret;
10033}
10034
10035#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070010036
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010037static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010038 struct net_device *dev,
10039 struct bss_parameters *params)
10040{
10041 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010042 hdd_context_t *pHddCtx;
10043 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010044
10045 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010046
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010047 if (NULL == pAdapter)
10048 {
10049 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10050 "%s: HDD adapter is Null", __func__);
10051 return -ENODEV;
10052 }
10053 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010054 ret = wlan_hdd_validate_context(pHddCtx);
10055 if (0 != ret)
10056 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010057 return ret;
10058 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010059 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10060 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
10061 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010062 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10063 __func__, hdd_device_modetoString(pAdapter->device_mode),
10064 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010065
10066 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010067 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010068 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010069 {
10070 /* ap_isolate == -1 means that in change bss, upper layer doesn't
10071 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010072 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -070010073 {
10074 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010075 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010076 }
10077
10078 EXIT();
10079 return 0;
10080}
10081
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053010082static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
10083 struct net_device *dev,
10084 struct bss_parameters *params)
10085{
10086 int ret;
10087
10088 vos_ssr_protect(__func__);
10089 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
10090 vos_ssr_unprotect(__func__);
10091
10092 return ret;
10093}
Kiet Lam10841362013-11-01 11:36:50 +053010094/* FUNCTION: wlan_hdd_change_country_code_cd
10095* to wait for contry code completion
10096*/
10097void* wlan_hdd_change_country_code_cb(void *pAdapter)
10098{
10099 hdd_adapter_t *call_back_pAdapter = pAdapter;
10100 complete(&call_back_pAdapter->change_country_code);
10101 return NULL;
10102}
10103
Jeff Johnson295189b2012-06-20 16:38:30 -070010104/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010105 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -070010106 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
10107 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010108int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010109 struct net_device *ndev,
10110 enum nl80211_iftype type,
10111 u32 *flags,
10112 struct vif_params *params
10113 )
10114{
10115 struct wireless_dev *wdev;
10116 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010117 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -070010118 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010119 tCsrRoamProfile *pRoamProfile = NULL;
10120 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010121 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010122 eMib_dot11DesiredBssType connectedBssType;
10123 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010124 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070010125
10126 ENTER();
10127
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010128 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010129 {
10130 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10131 "%s: Adapter context is null", __func__);
10132 return VOS_STATUS_E_FAILURE;
10133 }
10134
10135 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10136 if (!pHddCtx)
10137 {
10138 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10139 "%s: HDD context is null", __func__);
10140 return VOS_STATUS_E_FAILURE;
10141 }
10142
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010143 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10144 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
10145 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010146 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010147 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070010148 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010149 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010150 }
10151
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010152 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10153 __func__, hdd_device_modetoString(pAdapter->device_mode),
10154 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010155
Agarwal Ashish51325b52014-06-16 16:50:49 +053010156 if (vos_max_concurrent_connections_reached()) {
10157 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
10158 return -EINVAL;
10159 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010160 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070010161 wdev = ndev->ieee80211_ptr;
10162
10163#ifdef WLAN_BTAMP_FEATURE
10164 if((NL80211_IFTYPE_P2P_CLIENT == type)||
10165 (NL80211_IFTYPE_ADHOC == type)||
10166 (NL80211_IFTYPE_AP == type)||
10167 (NL80211_IFTYPE_P2P_GO == type))
10168 {
10169 pHddCtx->isAmpAllowed = VOS_FALSE;
10170 // stop AMP traffic
10171 status = WLANBAP_StopAmp();
10172 if(VOS_STATUS_SUCCESS != status )
10173 {
10174 pHddCtx->isAmpAllowed = VOS_TRUE;
10175 hddLog(VOS_TRACE_LEVEL_FATAL,
10176 "%s: Failed to stop AMP", __func__);
10177 return -EINVAL;
10178 }
10179 }
10180#endif //WLAN_BTAMP_FEATURE
10181 /* Reset the current device mode bit mask*/
10182 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
10183
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +053010184 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
10185 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
10186 (type == NL80211_IFTYPE_P2P_GO)))
10187 {
10188 /* Notify Mode change in case of concurrency.
10189 * Below function invokes TDLS teardown Functionality Since TDLS is
10190 * not Supported in case of concurrency i.e Once P2P session
10191 * is detected disable offchannel and teardown TDLS links
10192 */
10193 hddLog(LOG1,
10194 FL("Device mode = %d Interface type = %d"),
10195 pAdapter->device_mode, type);
10196 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
10197 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +053010198
Jeff Johnson295189b2012-06-20 16:38:30 -070010199 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010200 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -070010201 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010202 )
10203 {
10204 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080010205 if (!pWextState)
10206 {
10207 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10208 "%s: pWextState is null", __func__);
10209 return VOS_STATUS_E_FAILURE;
10210 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010211 pRoamProfile = &pWextState->roamProfile;
10212 LastBSSType = pRoamProfile->BSSType;
10213
10214 switch (type)
10215 {
10216 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010217 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010218 hddLog(VOS_TRACE_LEVEL_INFO,
10219 "%s: setting interface Type to INFRASTRUCTURE", __func__);
10220 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010221#ifdef WLAN_FEATURE_11AC
10222 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
10223 {
10224 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
10225 }
10226#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010227 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -070010228 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010229 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010230 //Check for sub-string p2p to confirm its a p2p interface
10231 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010232 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +053010233#ifdef FEATURE_WLAN_TDLS
10234 mutex_lock(&pHddCtx->tdls_lock);
10235 wlan_hdd_tdls_exit(pAdapter, TRUE);
10236 mutex_unlock(&pHddCtx->tdls_lock);
10237#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010238 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10239 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10240 }
10241 else
10242 {
10243 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010244 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010245 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010246 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +053010247
Jeff Johnson295189b2012-06-20 16:38:30 -070010248 case NL80211_IFTYPE_ADHOC:
10249 hddLog(VOS_TRACE_LEVEL_INFO,
10250 "%s: setting interface Type to ADHOC", __func__);
10251 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
10252 pRoamProfile->phyMode =
10253 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -070010254 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -070010255 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +053010256 hdd_set_ibss_ops( pAdapter );
10257 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +053010258
10259 status = hdd_sta_id_hash_attach(pAdapter);
10260 if (VOS_STATUS_SUCCESS != status) {
10261 hddLog(VOS_TRACE_LEVEL_ERROR,
10262 FL("Failed to initialize hash for IBSS"));
10263 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010264 break;
10265
10266 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010267 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010268 {
10269 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
10270 "%s: setting interface Type to %s", __func__,
10271 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
10272
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010273 //Cancel any remain on channel for GO mode
10274 if (NL80211_IFTYPE_P2P_GO == type)
10275 {
10276 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
10277 }
Mohit Khanna0f232092012-09-11 14:46:08 -070010278 if (NL80211_IFTYPE_AP == type)
10279 {
10280 /* As Loading WLAN Driver one interface being created for p2p device
10281 * address. This will take one HW STA and the max number of clients
10282 * that can connect to softAP will be reduced by one. so while changing
10283 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
10284 * interface as it is not required in SoftAP mode.
10285 */
10286
10287 // Get P2P Adapter
10288 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
10289
10290 if (pP2pAdapter)
10291 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +053010292 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +053010293 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -070010294 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
10295 }
10296 }
Swaroop Goltia2e32212014-04-09 23:37:33 +053010297 //Disable IMPS & BMPS for SAP/GO
10298 if(VOS_STATUS_E_FAILURE ==
10299 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
10300 {
10301 //Fail to Exit BMPS
10302 VOS_ASSERT(0);
10303 }
Deepthi Gowri500fc472014-08-11 19:53:10 +053010304
10305 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
10306
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010307#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -070010308
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010309 /* A Mutex Lock is introduced while changing the mode to
10310 * protect the concurrent access for the Adapters by TDLS
10311 * module.
10312 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010313 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010314#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010315 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +053010316 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010317 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -070010318 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10319 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010320#ifdef FEATURE_WLAN_TDLS
10321 mutex_unlock(&pHddCtx->tdls_lock);
10322#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010323 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
10324 (pConfig->apRandomBssidEnabled))
10325 {
10326 /* To meet Android requirements create a randomized
10327 MAC address of the form 02:1A:11:Fx:xx:xx */
10328 get_random_bytes(&ndev->dev_addr[3], 3);
10329 ndev->dev_addr[0] = 0x02;
10330 ndev->dev_addr[1] = 0x1A;
10331 ndev->dev_addr[2] = 0x11;
10332 ndev->dev_addr[3] |= 0xF0;
10333 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
10334 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -080010335 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
10336 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -070010337 }
10338
Jeff Johnson295189b2012-06-20 16:38:30 -070010339 hdd_set_ap_ops( pAdapter->dev );
10340
Kiet Lam10841362013-11-01 11:36:50 +053010341 /* This is for only SAP mode where users can
10342 * control country through ini.
10343 * P2P GO follows station country code
10344 * acquired during the STA scanning. */
10345 if((NL80211_IFTYPE_AP == type) &&
10346 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
10347 {
10348 int status = 0;
10349 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
10350 "%s: setting country code from INI ", __func__);
10351 init_completion(&pAdapter->change_country_code);
10352 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
10353 (void *)(tSmeChangeCountryCallback)
10354 wlan_hdd_change_country_code_cb,
10355 pConfig->apCntryCode, pAdapter,
10356 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +053010357 eSIR_FALSE,
10358 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +053010359 if (eHAL_STATUS_SUCCESS == status)
10360 {
10361 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010362 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +053010363 &pAdapter->change_country_code,
10364 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010365 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +053010366 {
10367 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010368 FL("SME Timed out while setting country code %ld"),
10369 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -080010370
10371 if (pHddCtx->isLogpInProgress)
10372 {
10373 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10374 "%s: LOGP in Progress. Ignore!!!", __func__);
10375 return -EAGAIN;
10376 }
Kiet Lam10841362013-11-01 11:36:50 +053010377 }
10378 }
10379 else
10380 {
10381 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010382 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +053010383 return -EINVAL;
10384 }
10385 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010386 status = hdd_init_ap_mode(pAdapter);
10387 if(status != VOS_STATUS_SUCCESS)
10388 {
10389 hddLog(VOS_TRACE_LEVEL_FATAL,
10390 "%s: Error initializing the ap mode", __func__);
10391 return -EINVAL;
10392 }
10393 hdd_set_conparam(1);
10394
Nirav Shah7e3c8132015-06-22 23:51:42 +053010395 status = hdd_sta_id_hash_attach(pAdapter);
10396 if (VOS_STATUS_SUCCESS != status)
10397 {
10398 hddLog(VOS_TRACE_LEVEL_ERROR,
10399 FL("Failed to initialize hash for AP"));
10400 return -EINVAL;
10401 }
10402
Jeff Johnson295189b2012-06-20 16:38:30 -070010403 /*interface type changed update in wiphy structure*/
10404 if(wdev)
10405 {
10406 wdev->iftype = type;
10407 pHddCtx->change_iface = type;
10408 }
10409 else
10410 {
10411 hddLog(VOS_TRACE_LEVEL_ERROR,
10412 "%s: ERROR !!!! Wireless dev is NULL", __func__);
10413 return -EINVAL;
10414 }
10415 goto done;
10416 }
10417
10418 default:
10419 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10420 __func__);
10421 return -EOPNOTSUPP;
10422 }
10423 }
10424 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010425 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -070010426 )
10427 {
10428 switch(type)
10429 {
10430 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -070010431 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -070010432 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +053010433
10434 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010435#ifdef FEATURE_WLAN_TDLS
10436
10437 /* A Mutex Lock is introduced while changing the mode to
10438 * protect the concurrent access for the Adapters by TDLS
10439 * module.
10440 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010441 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010442#endif
c_hpothu002231a2015-02-05 14:58:51 +053010443 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -070010444 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -080010445 //Check for sub-string p2p to confirm its a p2p interface
10446 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010447 {
10448 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
10449 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
10450 }
10451 else
10452 {
10453 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -070010454 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -080010455 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010456 hdd_set_conparam(0);
10457 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010458 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
10459 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053010460#ifdef FEATURE_WLAN_TDLS
10461 mutex_unlock(&pHddCtx->tdls_lock);
10462#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +053010463 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -070010464 if( VOS_STATUS_SUCCESS != status )
10465 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -070010466 /* In case of JB, for P2P-GO, only change interface will be called,
10467 * This is the right place to enable back bmps_imps()
10468 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053010469 if (pHddCtx->hdd_wlan_suspended)
10470 {
10471 hdd_set_pwrparams(pHddCtx);
10472 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010473 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -070010474 goto done;
10475 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -070010476 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -070010477 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -070010478 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
10479 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -070010480 goto done;
10481 default:
10482 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
10483 __func__);
10484 return -EOPNOTSUPP;
10485
10486 }
10487
10488 }
10489 else
10490 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010491 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
10492 __func__, hdd_device_modetoString(pAdapter->device_mode),
10493 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010494 return -EOPNOTSUPP;
10495 }
10496
10497
10498 if(pRoamProfile)
10499 {
10500 if ( LastBSSType != pRoamProfile->BSSType )
10501 {
10502 /*interface type changed update in wiphy structure*/
10503 wdev->iftype = type;
10504
10505 /*the BSS mode changed, We need to issue disconnect
10506 if connected or in IBSS disconnect state*/
10507 if ( hdd_connGetConnectedBssType(
10508 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
10509 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
10510 {
10511 /*need to issue a disconnect to CSR.*/
10512 INIT_COMPLETION(pAdapter->disconnect_comp_var);
10513 if( eHAL_STATUS_SUCCESS ==
10514 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
10515 pAdapter->sessionId,
10516 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
10517 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010518 ret = wait_for_completion_interruptible_timeout(
10519 &pAdapter->disconnect_comp_var,
10520 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
10521 if (ret <= 0)
10522 {
10523 hddLog(VOS_TRACE_LEVEL_ERROR,
10524 FL("wait on disconnect_comp_var failed %ld"), ret);
10525 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010526 }
10527 }
10528 }
10529 }
10530
10531done:
10532 /*set bitmask based on updated value*/
10533 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -070010534
10535 /* Only STA mode support TM now
10536 * all other mode, TM feature should be disabled */
10537 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
10538 (~VOS_STA & pHddCtx->concurrency_mode) )
10539 {
10540 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
10541 }
10542
Jeff Johnson295189b2012-06-20 16:38:30 -070010543#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010544 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053010545 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -070010546 {
10547 //we are ok to do AMP
10548 pHddCtx->isAmpAllowed = VOS_TRUE;
10549 }
10550#endif //WLAN_BTAMP_FEATURE
10551 EXIT();
10552 return 0;
10553}
10554
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +053010555/*
10556 * FUNCTION: wlan_hdd_cfg80211_change_iface
10557 * wrapper function to protect the actual implementation from SSR.
10558 */
10559int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
10560 struct net_device *ndev,
10561 enum nl80211_iftype type,
10562 u32 *flags,
10563 struct vif_params *params
10564 )
10565{
10566 int ret;
10567
10568 vos_ssr_protect(__func__);
10569 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
10570 vos_ssr_unprotect(__func__);
10571
10572 return ret;
10573}
10574
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010575#ifdef FEATURE_WLAN_TDLS
10576static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010577 struct net_device *dev,
10578#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10579 const u8 *mac,
10580#else
10581 u8 *mac,
10582#endif
10583 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010584{
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010585 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010586 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010587 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010588 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010589 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010590 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010591
10592 ENTER();
10593
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010594 if (!dev) {
10595 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
10596 return -EINVAL;
10597 }
10598
10599 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
10600 if (!pAdapter) {
10601 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
10602 return -EINVAL;
10603 }
10604
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010605 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010606 {
10607 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10608 "Invalid arguments");
10609 return -EINVAL;
10610 }
Hoonki Lee27511902013-03-14 18:19:06 -070010611
10612 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
10613 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
10614 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010615 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070010616 "%s: TDLS mode is disabled OR not enabled in FW."
10617 MAC_ADDRESS_STR " Request declined.",
10618 __func__, MAC_ADDR_ARRAY(mac));
10619 return -ENOTSUPP;
10620 }
10621
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010622 if (pHddCtx->isLogpInProgress)
10623 {
10624 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10625 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053010626 wlan_hdd_tdls_set_link_status(pAdapter,
10627 mac,
10628 eTDLS_LINK_IDLE,
10629 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010630 return -EBUSY;
10631 }
10632
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010633 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +053010634 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010635
10636 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010637 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010638 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
10639 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053010640 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010641 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010642 }
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010643
10644 /* in add station, we accept existing valid staId if there is */
10645 if ((0 == update) &&
10646 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
10647 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010648 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010649 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010650 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010651 " link_status %d. staId %d. add station ignored.",
10652 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010653 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010654 return 0;
10655 }
10656 /* in change station, we accept only when staId is valid */
10657 if ((1 == update) &&
10658 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
10659 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
10660 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010661 tANI_U16 staId = pTdlsPeer->staId;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010662 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010663 "%s: " MAC_ADDRESS_STR
10664 " link status %d. staId %d. change station %s.",
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010665 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, staId,
10666 (TDLS_STA_INDEX_VALID(staId)) ? "ignored" : "declined");
10667 mutex_unlock(&pHddCtx->tdls_lock);
10668 return (TDLS_STA_INDEX_VALID(staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010669 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010670 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010671
10672 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053010673 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010674 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010675 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10676 "%s: " MAC_ADDRESS_STR
10677 " TDLS setup is ongoing. Request declined.",
10678 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -070010679 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010680 }
10681
10682 /* first to check if we reached to maximum supported TDLS peer.
10683 TODO: for now, return -EPERM looks working fine,
10684 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010685 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
10686 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010687 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010688 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10689 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053010690 " TDLS Max peer already connected. Request declined."
10691 " Num of peers (%d), Max allowed (%d).",
10692 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
10693 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010694 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010695 }
10696 else
10697 {
10698 hddTdlsPeer_t *pTdlsPeer;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010699 mutex_lock(&pHddCtx->tdls_lock);
10700 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010701 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010702 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010703 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010704 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10705 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
10706 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010707 return -EPERM;
10708 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053010709 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010710 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010711 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +053010712 wlan_hdd_tdls_set_link_status(pAdapter,
10713 mac,
10714 eTDLS_LINK_CONNECTING,
10715 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010716
Jeff Johnsond75fe012013-04-06 10:53:06 -070010717 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010718 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010719 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010721 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010722 if(StaParams->htcap_present)
10723 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010725 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010727 "ht_capa->extended_capabilities: %0x",
10728 StaParams->HTCap.extendedHtCapInfo);
10729 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010730 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010731 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010733 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -070010734 if(StaParams->vhtcap_present)
10735 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -070010737 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
10738 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
10739 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
10740 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010741 {
10742 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010744 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053010745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010746 "[%d]: %x ", i, StaParams->supported_rates[i]);
10747 }
Jeff Johnsond75fe012013-04-06 10:53:06 -070010748 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +053010749 else if ((1 == update) && (NULL == StaParams))
10750 {
10751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10752 "%s : update is true, but staParams is NULL. Error!", __func__);
10753 return -EPERM;
10754 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010755
10756 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
10757
10758 if (!update)
10759 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010760 /*Before adding sta make sure that device exited from BMPS*/
10761 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
10762 {
10763 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10764 "%s: Adding tdls peer sta. Disable BMPS", __func__);
10765 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
10766 if (status != VOS_STATUS_SUCCESS) {
10767 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
10768 }
10769 }
10770
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010771 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010772 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010773 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +053010774 hddLog(VOS_TRACE_LEVEL_ERROR,
10775 FL("Failed to add TDLS peer STA. Enable Bmps"));
10776 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010777 return -EPERM;
10778 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010779 }
10780 else
10781 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010782 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010783 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053010784 if (ret != eHAL_STATUS_SUCCESS) {
10785 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
10786 return -EPERM;
10787 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010788 }
10789
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010790 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010791 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
10792
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010793 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010794 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010796 "%s: timeout waiting for tdls add station indication %ld",
10797 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010798 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010799 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010800
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010801 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
10802 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070010803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010804 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070010805 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010806 }
10807
10808 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -070010809
10810error:
Atul Mittal115287b2014-07-08 13:26:33 +053010811 wlan_hdd_tdls_set_link_status(pAdapter,
10812 mac,
10813 eTDLS_LINK_IDLE,
10814 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -070010815 return -EPERM;
10816
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010817}
10818#endif
10819
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010820static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010821 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010822#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10823 const u8 *mac,
10824#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010825 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010826#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010827 struct station_parameters *params)
10828{
10829 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010830 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010831 hdd_context_t *pHddCtx;
10832 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010833 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010834 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010835#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010836 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010837 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010838 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010839#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010840
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010841 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010842
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053010843 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010844 if ((NULL == pAdapter))
10845 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010846 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010847 "invalid adapter ");
10848 return -EINVAL;
10849 }
10850
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010851 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10852 TRACE_CODE_HDD_CHANGE_STATION,
10853 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +053010854 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +053010855
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010856 ret = wlan_hdd_validate_context(pHddCtx);
10857 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +053010858 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010859 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010860 }
10861
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010862 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10863
10864 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010865 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10867 "invalid HDD station context");
10868 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010869 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010870 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
10871
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010872 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
10873 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -070010874 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010875 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -070010876 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010877 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -070010878 WLANTL_STA_AUTHENTICATED);
10879
Gopichand Nakkala29149562013-05-10 21:43:41 +053010880 if (status != VOS_STATUS_SUCCESS)
10881 {
10882 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10883 "%s: Not able to change TL state to AUTHENTICATED", __func__);
10884 return -EINVAL;
10885 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010886 }
10887 }
Hoonki Leea6d49be2013-04-05 09:43:25 -070010888 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
10889 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +053010890#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010891 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
10892 StaParams.capability = params->capability;
10893 StaParams.uapsd_queues = params->uapsd_queues;
10894 StaParams.max_sp = params->max_sp;
10895
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010896 /* Convert (first channel , number of channels) tuple to
10897 * the total list of channels. This goes with the assumption
10898 * that if the first channel is < 14, then the next channels
10899 * are an incremental of 1 else an incremental of 4 till the number
10900 * of channels.
10901 */
10902 if (0 != params->supported_channels_len) {
10903 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
10904 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
10905 {
10906 int wifi_chan_index;
10907 StaParams.supported_channels[j] = params->supported_channels[i];
10908 wifi_chan_index =
10909 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
10910 no_of_channels = params->supported_channels[i+1];
10911 for(k=1; k <= no_of_channels; k++)
10912 {
10913 StaParams.supported_channels[j+1] =
10914 StaParams.supported_channels[j] + wifi_chan_index;
10915 j+=1;
10916 }
10917 }
10918 StaParams.supported_channels_len = j;
10919 }
10920 vos_mem_copy(StaParams.supported_oper_classes,
10921 params->supported_oper_classes,
10922 params->supported_oper_classes_len);
10923 StaParams.supported_oper_classes_len =
10924 params->supported_oper_classes_len;
10925
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010926 if (0 != params->ext_capab_len)
10927 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
10928 sizeof(StaParams.extn_capability));
10929
10930 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070010931 {
10932 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010933 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070010934 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010935
10936 StaParams.supported_rates_len = params->supported_rates_len;
10937
10938 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
10939 * The supported_rates array , for all the structures propogating till Add Sta
10940 * to the firmware has to be modified , if the supplicant (ieee80211) is
10941 * modified to send more rates.
10942 */
10943
10944 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
10945 */
10946 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
10947 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
10948
10949 if (0 != StaParams.supported_rates_len) {
10950 int i = 0;
10951 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
10952 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010953 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010954 "Supported Rates with Length %d", StaParams.supported_rates_len);
10955 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -070010956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010957 "[%d]: %0x", i, StaParams.supported_rates[i]);
10958 }
10959
10960 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -070010961 {
10962 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010963 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -070010964 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070010965
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010966 if (0 != params->ext_capab_len ) {
10967 /*Define A Macro : TODO Sunil*/
10968 if ((1<<4) & StaParams.extn_capability[3]) {
10969 isBufSta = 1;
10970 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010971 /* TDLS Channel Switching Support */
10972 if ((1<<6) & StaParams.extn_capability[3]) {
10973 isOffChannelSupported = 1;
10974 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010975 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +053010976 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
10977 &StaParams, isBufSta,
10978 isOffChannelSupported);
10979
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053010980 if (VOS_STATUS_SUCCESS != status) {
10981 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10982 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
10983 return -EINVAL;
10984 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010985 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
10986
10987 if (VOS_STATUS_SUCCESS != status) {
10988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10989 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
10990 return -EINVAL;
10991 }
10992 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -070010993#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +053010994 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010995 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010996 return status;
10997}
10998
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053010999#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
11000static int wlan_hdd_change_station(struct wiphy *wiphy,
11001 struct net_device *dev,
11002 const u8 *mac,
11003 struct station_parameters *params)
11004#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011005static int wlan_hdd_change_station(struct wiphy *wiphy,
11006 struct net_device *dev,
11007 u8 *mac,
11008 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011009#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011010{
11011 int ret;
11012
11013 vos_ssr_protect(__func__);
11014 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
11015 vos_ssr_unprotect(__func__);
11016
11017 return ret;
11018}
11019
Jeff Johnson295189b2012-06-20 16:38:30 -070011020/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011021 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011022 * This function is used to initialize the key information
11023 */
11024#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011025static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011026 struct net_device *ndev,
11027 u8 key_index, bool pairwise,
11028 const u8 *mac_addr,
11029 struct key_params *params
11030 )
11031#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011032static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011033 struct net_device *ndev,
11034 u8 key_index, const u8 *mac_addr,
11035 struct key_params *params
11036 )
11037#endif
11038{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011039 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070011040 tCsrRoamSetKey setKey;
11041 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011042 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011043 v_U32_t roamId= 0xFF;
11044 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011045 hdd_hostapd_state_t *pHostapdState;
11046 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011047 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011048 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011049
11050 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011051
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011052 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11053 TRACE_CODE_HDD_CFG80211_ADD_KEY,
11054 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011055 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11056 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011057 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011058 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011059 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011060 }
11061
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011062 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11063 __func__, hdd_device_modetoString(pAdapter->device_mode),
11064 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011065
11066 if (CSR_MAX_NUM_KEY <= key_index)
11067 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011068 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011069 key_index);
11070
11071 return -EINVAL;
11072 }
11073
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011074 if (CSR_MAX_KEY_LEN < params->key_len)
11075 {
11076 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
11077 params->key_len);
11078
11079 return -EINVAL;
11080 }
11081
11082 hddLog(VOS_TRACE_LEVEL_INFO,
11083 "%s: called with key index = %d & key length %d",
11084 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011085
11086 /*extract key idx, key len and key*/
11087 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11088 setKey.keyId = key_index;
11089 setKey.keyLength = params->key_len;
11090 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
11091
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011092 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011093 {
11094 case WLAN_CIPHER_SUITE_WEP40:
11095 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
11096 break;
11097
11098 case WLAN_CIPHER_SUITE_WEP104:
11099 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
11100 break;
11101
11102 case WLAN_CIPHER_SUITE_TKIP:
11103 {
11104 u8 *pKey = &setKey.Key[0];
11105 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
11106
11107 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
11108
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011109 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -070011110
11111 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011112 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011113 |--------------|----------|----------|
11114 <---16bytes---><--8bytes--><--8bytes-->
11115
11116 */
11117 /*Sme expects the 32 bytes key to be in the below order
11118
11119 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011120 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070011121 |--------------|----------|----------|
11122 <---16bytes---><--8bytes--><--8bytes-->
11123 */
11124 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011125 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070011126
11127 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011128 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011129
11130 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011131 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070011132
11133
11134 break;
11135 }
11136
11137 case WLAN_CIPHER_SUITE_CCMP:
11138 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
11139 break;
11140
11141#ifdef FEATURE_WLAN_WAPI
11142 case WLAN_CIPHER_SUITE_SMS4:
11143 {
11144 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11145 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
11146 params->key, params->key_len);
11147 return 0;
11148 }
11149#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011150
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011151#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011152 case WLAN_CIPHER_SUITE_KRK:
11153 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
11154 break;
11155#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070011156
11157#ifdef WLAN_FEATURE_11W
11158 case WLAN_CIPHER_SUITE_AES_CMAC:
11159 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070011160 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070011161#endif
11162
Jeff Johnson295189b2012-06-20 16:38:30 -070011163 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011164 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011165 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011166 status = -EOPNOTSUPP;
11167 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011168 }
11169
11170 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
11171 __func__, setKey.encType);
11172
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011173 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070011174#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11175 (!pairwise)
11176#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011177 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070011178#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011179 )
11180 {
11181 /* set group key*/
11182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11183 "%s- %d: setting Broadcast key",
11184 __func__, __LINE__);
11185 setKey.keyDirection = eSIR_RX_ONLY;
11186 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11187 }
11188 else
11189 {
11190 /* set pairwise key*/
11191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11192 "%s- %d: setting pairwise key",
11193 __func__, __LINE__);
11194 setKey.keyDirection = eSIR_TX_RX;
11195 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11196 }
11197 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
11198 {
11199 setKey.keyDirection = eSIR_TX_RX;
11200 /*Set the group key*/
11201 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11202 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070011203
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011204 if ( 0 != status )
11205 {
11206 hddLog(VOS_TRACE_LEVEL_ERROR,
11207 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011208 status = -EINVAL;
11209 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011210 }
11211 /*Save the keys here and call sme_RoamSetKey for setting
11212 the PTK after peer joins the IBSS network*/
11213 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
11214 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011215 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070011216 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053011217 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
11218 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
11219 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011220 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011221 if( pHostapdState->bssState == BSS_START )
11222 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011223 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11224 vos_status = wlan_hdd_check_ula_done(pAdapter);
11225
11226 if ( vos_status != VOS_STATUS_SUCCESS )
11227 {
11228 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11229 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11230 __LINE__, vos_status );
11231
11232 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11233
11234 status = -EINVAL;
11235 goto end;
11236 }
11237
Jeff Johnson295189b2012-06-20 16:38:30 -070011238 status = WLANSAP_SetKeySta( pVosContext, &setKey);
11239
11240 if ( status != eHAL_STATUS_SUCCESS )
11241 {
11242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11243 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11244 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011245 status = -EINVAL;
11246 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011247 }
11248 }
11249
11250 /* Saving WEP keys */
11251 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
11252 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
11253 {
11254 //Save the wep key in ap context. Issue setkey after the BSS is started.
11255 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11256 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
11257 }
11258 else
11259 {
11260 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011261 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011262 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
11263 }
11264 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011265 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
11266 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011267 {
11268 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11269 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11270
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011271#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11272 if (!pairwise)
11273#else
11274 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
11275#endif
11276 {
11277 /* set group key*/
11278 if (pHddStaCtx->roam_info.deferKeyComplete)
11279 {
11280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11281 "%s- %d: Perform Set key Complete",
11282 __func__, __LINE__);
11283 hdd_PerformRoamSetKeyComplete(pAdapter);
11284 }
11285 }
11286
Jeff Johnson295189b2012-06-20 16:38:30 -070011287 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
11288
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080011289 pWextState->roamProfile.Keys.defaultIndex = key_index;
11290
11291
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070011292 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011293 params->key, params->key_len);
11294
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011295
Jeff Johnson295189b2012-06-20 16:38:30 -070011296 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11297
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011298 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011299 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011300 __func__, setKey.peerMac[0], setKey.peerMac[1],
11301 setKey.peerMac[2], setKey.peerMac[3],
11302 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011303 setKey.keyDirection);
11304
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011305 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053011306
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011307 if ( vos_status != VOS_STATUS_SUCCESS )
11308 {
11309 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011310 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
11311 __LINE__, vos_status );
11312
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011313 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011314
Nirav Shah4b53d4b2015-05-08 05:35:00 -070011315 status = -EINVAL;
11316 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011317
11318 }
11319
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011320#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011321 /* The supplicant may attempt to set the PTK once pre-authentication
11322 is done. Save the key in the UMAC and include it in the ADD BSS
11323 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011324 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011325 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011326 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011327 hddLog(VOS_TRACE_LEVEL_INFO_MED,
11328 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011329 status = 0;
11330 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053011331 }
11332 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
11333 {
11334 hddLog(VOS_TRACE_LEVEL_ERROR,
11335 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011336 status = -EINVAL;
11337 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011338 }
11339#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070011340
11341 /* issue set key request to SME*/
11342 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
11343 pAdapter->sessionId, &setKey, &roamId );
11344
11345 if ( 0 != status )
11346 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011347 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011348 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
11349 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011350 status = -EINVAL;
11351 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011352 }
11353
11354
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011355 /* in case of IBSS as there was no information available about WEP keys during
11356 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070011357 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011358 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
11359 !( ( IW_AUTH_KEY_MGMT_802_1X
11360 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070011361 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
11362 )
11363 &&
11364 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
11365 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
11366 )
11367 )
11368 {
11369 setKey.keyDirection = eSIR_RX_ONLY;
11370 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
11371
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011372 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011373 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011374 __func__, setKey.peerMac[0], setKey.peerMac[1],
11375 setKey.peerMac[2], setKey.peerMac[3],
11376 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070011377 setKey.keyDirection);
11378
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011379 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011380 pAdapter->sessionId, &setKey, &roamId );
11381
11382 if ( 0 != status )
11383 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011384 hddLog(VOS_TRACE_LEVEL_ERROR,
11385 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011386 __func__, status);
11387 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011388 status = -EINVAL;
11389 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070011390 }
11391 }
11392 }
11393
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011394end:
11395 /* Need to clear any trace of key value in the memory.
11396 * Thus zero out the memory even though it is local
11397 * variable.
11398 */
11399 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011400 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053011401 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070011402}
11403
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011404#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11405static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11406 struct net_device *ndev,
11407 u8 key_index, bool pairwise,
11408 const u8 *mac_addr,
11409 struct key_params *params
11410 )
11411#else
11412static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
11413 struct net_device *ndev,
11414 u8 key_index, const u8 *mac_addr,
11415 struct key_params *params
11416 )
11417#endif
11418{
11419 int ret;
11420 vos_ssr_protect(__func__);
11421#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11422 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
11423 mac_addr, params);
11424#else
11425 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
11426 params);
11427#endif
11428 vos_ssr_unprotect(__func__);
11429
11430 return ret;
11431}
11432
Jeff Johnson295189b2012-06-20 16:38:30 -070011433/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011434 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011435 * This function is used to get the key information
11436 */
11437#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011438static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011439 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011440 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011441 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011442 const u8 *mac_addr, void *cookie,
11443 void (*callback)(void *cookie, struct key_params*)
11444 )
11445#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011446static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011447 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011448 struct net_device *ndev,
11449 u8 key_index, const u8 *mac_addr, void *cookie,
11450 void (*callback)(void *cookie, struct key_params*)
11451 )
11452#endif
11453{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011454 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011455 hdd_wext_state_t *pWextState = NULL;
11456 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011457 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011458 hdd_context_t *pHddCtx;
11459 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011460
11461 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011462
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011463 if (NULL == pAdapter)
11464 {
11465 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11466 "%s: HDD adapter is Null", __func__);
11467 return -ENODEV;
11468 }
11469
11470 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11471 ret = wlan_hdd_validate_context(pHddCtx);
11472 if (0 != ret)
11473 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053011474 return ret;
11475 }
11476
11477 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11478 pRoamProfile = &(pWextState->roamProfile);
11479
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011480 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11481 __func__, hdd_device_modetoString(pAdapter->device_mode),
11482 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011483
Jeff Johnson295189b2012-06-20 16:38:30 -070011484 memset(&params, 0, sizeof(params));
11485
11486 if (CSR_MAX_NUM_KEY <= key_index)
11487 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011488 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070011489 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011490 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011491
11492 switch(pRoamProfile->EncryptionType.encryptionType[0])
11493 {
11494 case eCSR_ENCRYPT_TYPE_NONE:
11495 params.cipher = IW_AUTH_CIPHER_NONE;
11496 break;
11497
11498 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
11499 case eCSR_ENCRYPT_TYPE_WEP40:
11500 params.cipher = WLAN_CIPHER_SUITE_WEP40;
11501 break;
11502
11503 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
11504 case eCSR_ENCRYPT_TYPE_WEP104:
11505 params.cipher = WLAN_CIPHER_SUITE_WEP104;
11506 break;
11507
11508 case eCSR_ENCRYPT_TYPE_TKIP:
11509 params.cipher = WLAN_CIPHER_SUITE_TKIP;
11510 break;
11511
11512 case eCSR_ENCRYPT_TYPE_AES:
11513 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
11514 break;
11515
11516 default:
11517 params.cipher = IW_AUTH_CIPHER_NONE;
11518 break;
11519 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011520
c_hpothuaaf19692014-05-17 17:01:48 +053011521 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11522 TRACE_CODE_HDD_CFG80211_GET_KEY,
11523 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011524
Jeff Johnson295189b2012-06-20 16:38:30 -070011525 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
11526 params.seq_len = 0;
11527 params.seq = NULL;
11528 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
11529 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011530 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011531 return 0;
11532}
11533
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011534#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11535static int wlan_hdd_cfg80211_get_key(
11536 struct wiphy *wiphy,
11537 struct net_device *ndev,
11538 u8 key_index, bool pairwise,
11539 const u8 *mac_addr, void *cookie,
11540 void (*callback)(void *cookie, struct key_params*)
11541 )
11542#else
11543static int wlan_hdd_cfg80211_get_key(
11544 struct wiphy *wiphy,
11545 struct net_device *ndev,
11546 u8 key_index, const u8 *mac_addr, void *cookie,
11547 void (*callback)(void *cookie, struct key_params*)
11548 )
11549#endif
11550{
11551 int ret;
11552
11553 vos_ssr_protect(__func__);
11554#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11555 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
11556 mac_addr, cookie, callback);
11557#else
11558 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
11559 callback);
11560#endif
11561 vos_ssr_unprotect(__func__);
11562
11563 return ret;
11564}
11565
Jeff Johnson295189b2012-06-20 16:38:30 -070011566/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011567 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011568 * This function is used to delete the key information
11569 */
11570#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011571static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011572 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011573 u8 key_index,
11574 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070011575 const u8 *mac_addr
11576 )
11577#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011578static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011579 struct net_device *ndev,
11580 u8 key_index,
11581 const u8 *mac_addr
11582 )
11583#endif
11584{
11585 int status = 0;
11586
11587 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011588 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070011589 //it is observed that this is invalidating peer
11590 //key index whenever re-key is done. This is affecting data link.
11591 //It should be ok to ignore del_key.
11592#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011593 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
11594 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070011595 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
11596 tCsrRoamSetKey setKey;
11597 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011598
Jeff Johnson295189b2012-06-20 16:38:30 -070011599 ENTER();
11600
11601 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
11602 __func__,pAdapter->device_mode);
11603
11604 if (CSR_MAX_NUM_KEY <= key_index)
11605 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011606 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011607 key_index);
11608
11609 return -EINVAL;
11610 }
11611
11612 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11613 setKey.keyId = key_index;
11614
11615 if (mac_addr)
11616 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
11617 else
11618 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
11619
11620 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
11621
11622 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011623 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011624 )
11625 {
11626
11627 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070011628 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
11629 if( pHostapdState->bssState == BSS_START)
11630 {
11631 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011632
Jeff Johnson295189b2012-06-20 16:38:30 -070011633 if ( status != eHAL_STATUS_SUCCESS )
11634 {
11635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11636 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
11637 __LINE__, status );
11638 }
11639 }
11640 }
11641 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011642 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070011643 )
11644 {
11645 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11646
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011647 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
11648
11649 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070011650 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011651 __func__, setKey.peerMac[0], setKey.peerMac[1],
11652 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070011653 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011654 if(pAdapter->sessionCtx.station.conn_info.connState ==
11655 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070011656 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011657 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011658 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011659
Jeff Johnson295189b2012-06-20 16:38:30 -070011660 if ( 0 != status )
11661 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011662 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011663 "%s: sme_RoamSetKey failure, returned %d",
11664 __func__, status);
11665 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
11666 return -EINVAL;
11667 }
11668 }
11669 }
11670#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070011671 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011672 return status;
11673}
11674
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053011675#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11676static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11677 struct net_device *ndev,
11678 u8 key_index,
11679 bool pairwise,
11680 const u8 *mac_addr
11681 )
11682#else
11683static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
11684 struct net_device *ndev,
11685 u8 key_index,
11686 const u8 *mac_addr
11687 )
11688#endif
11689{
11690 int ret;
11691
11692 vos_ssr_protect(__func__);
11693#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11694 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
11695 mac_addr);
11696#else
11697 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
11698#endif
11699 vos_ssr_unprotect(__func__);
11700
11701 return ret;
11702}
11703
Jeff Johnson295189b2012-06-20 16:38:30 -070011704/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011705 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070011706 * This function is used to set the default tx key index
11707 */
11708#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011709static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011710 struct net_device *ndev,
11711 u8 key_index,
11712 bool unicast, bool multicast)
11713#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011714static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011715 struct net_device *ndev,
11716 u8 key_index)
11717#endif
11718{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011719 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011720 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053011721 hdd_wext_state_t *pWextState;
11722 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011723 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011724
11725 ENTER();
11726
Gopichand Nakkala29149562013-05-10 21:43:41 +053011727 if ((NULL == pAdapter))
11728 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011729 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053011730 "invalid adapter");
11731 return -EINVAL;
11732 }
11733
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011734 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11735 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
11736 pAdapter->sessionId, key_index));
11737
Gopichand Nakkala29149562013-05-10 21:43:41 +053011738 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11739 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11740
11741 if ((NULL == pWextState) || (NULL == pHddStaCtx))
11742 {
11743 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11744 "invalid Wext state or HDD context");
11745 return -EINVAL;
11746 }
11747
Arif Hussain6d2a3322013-11-17 19:50:10 -080011748 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011749 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011750
Jeff Johnson295189b2012-06-20 16:38:30 -070011751 if (CSR_MAX_NUM_KEY <= key_index)
11752 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011753 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011754 key_index);
11755
11756 return -EINVAL;
11757 }
11758
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011759 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11760 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011761 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011762 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011763 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011764 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011765
Jeff Johnson295189b2012-06-20 16:38:30 -070011766 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070011767 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011768 )
Jeff Johnson295189b2012-06-20 16:38:30 -070011769 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053011770 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080011771 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011772 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080011773 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070011774 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011775 {
11776 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070011777 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011778
Jeff Johnson295189b2012-06-20 16:38:30 -070011779 tCsrRoamSetKey setKey;
11780 v_U32_t roamId= 0xFF;
11781 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011782
11783 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011784 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011785
Jeff Johnson295189b2012-06-20 16:38:30 -070011786 Keys->defaultIndex = (u8)key_index;
11787 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
11788 setKey.keyId = key_index;
11789 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011790
11791 vos_mem_copy(&setKey.Key[0],
11792 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070011793 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011794
Gopichand Nakkala29149562013-05-10 21:43:41 +053011795 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011796
11797 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070011798 &pHddStaCtx->conn_info.bssId[0],
11799 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011800
Gopichand Nakkala29149562013-05-10 21:43:41 +053011801 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
11802 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
11803 eCSR_ENCRYPT_TYPE_WEP104)
11804 {
11805 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
11806 even though ap is configured for WEP-40 encryption. In this canse the key length
11807 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
11808 type(104) and switching encryption type to 40*/
11809 pWextState->roamProfile.EncryptionType.encryptionType[0] =
11810 eCSR_ENCRYPT_TYPE_WEP40;
11811 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
11812 eCSR_ENCRYPT_TYPE_WEP40;
11813 }
11814
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011815 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070011816 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011817
Jeff Johnson295189b2012-06-20 16:38:30 -070011818 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011819 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011820 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011821
Jeff Johnson295189b2012-06-20 16:38:30 -070011822 if ( 0 != status )
11823 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011824 hddLog(VOS_TRACE_LEVEL_ERROR,
11825 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011826 status);
11827 return -EINVAL;
11828 }
11829 }
11830 }
11831
11832 /* In SoftAp mode setting key direction for default mode */
11833 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
11834 {
11835 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
11836 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
11837 (eCSR_ENCRYPT_TYPE_AES !=
11838 pWextState->roamProfile.EncryptionType.encryptionType[0])
11839 )
11840 {
11841 /* Saving key direction for default key index to TX default */
11842 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
11843 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
11844 }
11845 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011846 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011847 return status;
11848}
11849
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053011850#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11851static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
11852 struct net_device *ndev,
11853 u8 key_index,
11854 bool unicast, bool multicast)
11855#else
11856static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
11857 struct net_device *ndev,
11858 u8 key_index)
11859#endif
11860{
11861 int ret;
11862 vos_ssr_protect(__func__);
11863#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
11864 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
11865 multicast);
11866#else
11867 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
11868#endif
11869 vos_ssr_unprotect(__func__);
11870
11871 return ret;
11872}
11873
Jeff Johnson295189b2012-06-20 16:38:30 -070011874/*
11875 * FUNCTION: wlan_hdd_cfg80211_inform_bss
11876 * This function is used to inform the BSS details to nl80211 interface.
11877 */
11878static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
11879 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
11880{
11881 struct net_device *dev = pAdapter->dev;
11882 struct wireless_dev *wdev = dev->ieee80211_ptr;
11883 struct wiphy *wiphy = wdev->wiphy;
11884 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
11885 int chan_no;
11886 int ie_length;
11887 const char *ie;
11888 unsigned int freq;
11889 struct ieee80211_channel *chan;
11890 int rssi = 0;
11891 struct cfg80211_bss *bss = NULL;
11892
Jeff Johnson295189b2012-06-20 16:38:30 -070011893 if( NULL == pBssDesc )
11894 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011895 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011896 return bss;
11897 }
11898
11899 chan_no = pBssDesc->channelId;
11900 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
11901 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
11902
11903 if( NULL == ie )
11904 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011905 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011906 return bss;
11907 }
11908
11909#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
11910 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
11911 {
11912 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
11913 }
11914 else
11915 {
11916 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
11917 }
11918#else
11919 freq = ieee80211_channel_to_frequency(chan_no);
11920#endif
11921
11922 chan = __ieee80211_get_channel(wiphy, freq);
11923
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053011924 if (!chan) {
11925 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
11926 return NULL;
11927 }
11928
Abhishek Singhaee43942014-06-16 18:55:47 +053011929 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070011930
Anand N Sunkad9f80b742015-07-30 20:05:51 +053011931 return cfg80211_inform_bss(wiphy, chan,
11932#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11933 CFG80211_BSS_FTYPE_UNKNOWN,
11934#endif
11935 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011936 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070011937 pBssDesc->capabilityInfo,
11938 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053011939 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070011940}
11941
11942
11943
11944/*
11945 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
11946 * This function is used to inform the BSS details to nl80211 interface.
11947 */
11948struct cfg80211_bss*
11949wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
11950 tSirBssDescription *bss_desc
11951 )
11952{
11953 /*
11954 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
11955 already exists in bss data base of cfg80211 for that particular BSS ID.
11956 Using cfg80211_inform_bss_frame to update the bss entry instead of
11957 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
11958 now there is no possibility to get the mgmt(probe response) frame from PE,
11959 converting bss_desc to ieee80211_mgmt(probe response) and passing to
11960 cfg80211_inform_bss_frame.
11961 */
11962 struct net_device *dev = pAdapter->dev;
11963 struct wireless_dev *wdev = dev->ieee80211_ptr;
11964 struct wiphy *wiphy = wdev->wiphy;
11965 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080011966#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
11967 qcom_ie_age *qie_age = NULL;
11968 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
11969#else
Jeff Johnson295189b2012-06-20 16:38:30 -070011970 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080011971#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011972 const char *ie =
11973 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
11974 unsigned int freq;
11975 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053011976 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011977 struct cfg80211_bss *bss_status = NULL;
11978 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
11979 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070011980 hdd_context_t *pHddCtx;
11981 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070011982#ifdef WLAN_OPEN_SOURCE
11983 struct timespec ts;
11984#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011985
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053011986
Wilson Yangf80a0542013-10-07 13:02:37 -070011987 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11988 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070011989 if (0 != status)
11990 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070011991 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070011992 }
11993
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053011994 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070011995 if (!mgmt)
11996 {
11997 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11998 "%s: memory allocation failed ", __func__);
11999 return NULL;
12000 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070012001
Jeff Johnson295189b2012-06-20 16:38:30 -070012002 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012003
12004#ifdef WLAN_OPEN_SOURCE
12005 /* Android does not want the timestamp from the frame.
12006 Instead it wants a monotonic increasing value */
12007 get_monotonic_boottime(&ts);
12008 mgmt->u.probe_resp.timestamp =
12009 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
12010#else
12011 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012012 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
12013 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070012014
12015#endif
12016
Jeff Johnson295189b2012-06-20 16:38:30 -070012017 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
12018 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080012019
12020#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
12021 /* GPS Requirement: need age ie per entry. Using vendor specific. */
12022 /* Assuming this is the last IE, copy at the end */
12023 ie_length -=sizeof(qcom_ie_age);
12024 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
12025 qie_age->element_id = QCOM_VENDOR_IE_ID;
12026 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
12027 qie_age->oui_1 = QCOM_OUI1;
12028 qie_age->oui_2 = QCOM_OUI2;
12029 qie_age->oui_3 = QCOM_OUI3;
12030 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
12031 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
12032#endif
12033
Jeff Johnson295189b2012-06-20 16:38:30 -070012034 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053012035 if (bss_desc->fProbeRsp)
12036 {
12037 mgmt->frame_control |=
12038 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
12039 }
12040 else
12041 {
12042 mgmt->frame_control |=
12043 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
12044 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012045
12046#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012047 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012048 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
12049 {
12050 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
12051 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012052 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070012053 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
12054
12055 {
12056 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
12057 }
12058 else
12059 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012060 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
12061 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070012062 kfree(mgmt);
12063 return NULL;
12064 }
12065#else
12066 freq = ieee80211_channel_to_frequency(chan_no);
12067#endif
12068 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012069 /*when the band is changed on the fly using the GUI, three things are done
12070 * 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)
12071 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
12072 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
12073 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
12074 * and discards the channels correponding to previous band and calls back with zero bss results.
12075 * 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
12076 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
12077 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
12078 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
12079 * So drop the bss and continue to next bss.
12080 */
12081 if(chan == NULL)
12082 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012083 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070012084 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080012085 return NULL;
12086 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053012087 /*To keep the rssi icon of the connected AP in the scan window
12088 *and the rssi icon of the wireless networks in sync
12089 * */
12090 if (( eConnectionState_Associated ==
12091 pAdapter->sessionCtx.station.conn_info.connState ) &&
12092 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
12093 pAdapter->sessionCtx.station.conn_info.bssId,
12094 WNI_CFG_BSSID_LEN)) &&
12095 (pHddCtx->hdd_wlan_suspended == FALSE))
12096 {
12097 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
12098 rssi = (pAdapter->rssi * 100);
12099 }
12100 else
12101 {
12102 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
12103 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012104
Nirav Shah20ac06f2013-12-12 18:14:06 +053012105 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053012106 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
12107 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053012108
Jeff Johnson295189b2012-06-20 16:38:30 -070012109 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
12110 frame_len, rssi, GFP_KERNEL);
12111 kfree(mgmt);
12112 return bss_status;
12113}
12114
12115/*
12116 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
12117 * This function is used to update the BSS data base of CFG8011
12118 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012119struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012120 tCsrRoamInfo *pRoamInfo
12121 )
12122{
12123 tCsrRoamConnectedProfile roamProfile;
12124 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12125 struct cfg80211_bss *bss = NULL;
12126
12127 ENTER();
12128
12129 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
12130 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
12131
12132 if (NULL != roamProfile.pBssDesc)
12133 {
Girish Gowlif4b68022014-08-28 23:18:57 +053012134 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12135 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070012136
12137 if (NULL == bss)
12138 {
12139 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
12140 __func__);
12141 }
12142
12143 sme_RoamFreeConnectProfile(hHal, &roamProfile);
12144 }
12145 else
12146 {
12147 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
12148 __func__);
12149 }
12150 return bss;
12151}
12152
12153/*
12154 * FUNCTION: wlan_hdd_cfg80211_update_bss
12155 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012156static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
12157 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070012158 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012159{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012160 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012161 tCsrScanResultInfo *pScanResult;
12162 eHalStatus status = 0;
12163 tScanResultHandle pResult;
12164 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070012165 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012166 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070012167 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012168
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012169 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12170 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
12171 NO_SESSION, pAdapter->sessionId));
12172
Wilson Yangf80a0542013-10-07 13:02:37 -070012173 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12174
12175 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070012176 {
Wilson Yangf80a0542013-10-07 13:02:37 -070012177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
12178 "%s:LOGP in Progress. Ignore!!!",__func__);
12179 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070012180 }
12181
Wilson Yangf80a0542013-10-07 13:02:37 -070012182
12183 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053012184 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070012185 {
12186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12187 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
12188 return VOS_STATUS_E_PERM;
12189 }
12190
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012191 if (pAdapter->request != NULL)
12192 {
12193 if ((pAdapter->request->n_ssids == 1)
12194 && (pAdapter->request->ssids != NULL)
12195 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
12196 is_p2p_scan = true;
12197 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012198 /*
12199 * start getting scan results and populate cgf80211 BSS database
12200 */
12201 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
12202
12203 /* no scan results */
12204 if (NULL == pResult)
12205 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012206 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
12207 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053012208 wlan_hdd_get_frame_logs(pAdapter,
12209 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070012210 return status;
12211 }
12212
12213 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
12214
12215 while (pScanResult)
12216 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012217 /*
12218 * cfg80211_inform_bss() is not updating ie field of bss entry, if
12219 * entry already exists in bss data base of cfg80211 for that
12220 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
12221 * bss entry instead of cfg80211_inform_bss, But this call expects
12222 * mgmt packet as input. As of now there is no possibility to get
12223 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070012224 * ieee80211_mgmt(probe response) and passing to c
12225 * fg80211_inform_bss_frame.
12226 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012227 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
12228 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
12229 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012230 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12231 continue; //Skip the non p2p bss entries
12232 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012233 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
12234 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012235
Jeff Johnson295189b2012-06-20 16:38:30 -070012236
12237 if (NULL == bss_status)
12238 {
12239 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012240 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012241 }
12242 else
12243 {
Yue Maf49ba872013-08-19 12:04:25 -070012244 cfg80211_put_bss(
12245#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
12246 wiphy,
12247#endif
12248 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070012249 }
12250
12251 pScanResult = sme_ScanResultGetNext(hHal, pResult);
12252 }
12253
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012254 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053012255 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012256 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012257}
12258
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012259void
12260hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
12261{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012262 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080012263 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012264} /****** end hddPrintMacAddr() ******/
12265
12266void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012267hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012268{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012269 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012270 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070012271 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
12272 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
12273 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012274} /****** end hddPrintPmkId() ******/
12275
12276//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
12277//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
12278
12279//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
12280//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
12281
12282#define dump_bssid(bssid) \
12283 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012284 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
12285 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012286 }
12287
12288#define dump_pmkid(pMac, pmkid) \
12289 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070012290 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
12291 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012292 }
12293
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070012294#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012295/*
12296 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
12297 * This function is used to notify the supplicant of a new PMKSA candidate.
12298 */
12299int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012300 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012301 int index, bool preauth )
12302{
Jeff Johnsone7245742012-09-05 17:12:55 -070012303#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012304 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012305 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012306
12307 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070012308 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012309
12310 if( NULL == pRoamInfo )
12311 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012312 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012313 return -EINVAL;
12314 }
12315
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012316 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
12317 {
12318 dump_bssid(pRoamInfo->bssid);
12319 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012320 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070012321 }
Jeff Johnsone7245742012-09-05 17:12:55 -070012322#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012323 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012324}
12325#endif //FEATURE_WLAN_LFR
12326
Yue Maef608272013-04-08 23:09:17 -070012327#ifdef FEATURE_WLAN_LFR_METRICS
12328/*
12329 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
12330 * 802.11r/LFR metrics reporting function to report preauth initiation
12331 *
12332 */
12333#define MAX_LFR_METRICS_EVENT_LENGTH 100
12334VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
12335 tCsrRoamInfo *pRoamInfo)
12336{
12337 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12338 union iwreq_data wrqu;
12339
12340 ENTER();
12341
12342 if (NULL == pAdapter)
12343 {
12344 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12345 return VOS_STATUS_E_FAILURE;
12346 }
12347
12348 /* create the event */
12349 memset(&wrqu, 0, sizeof(wrqu));
12350 memset(metrics_notification, 0, sizeof(metrics_notification));
12351
12352 wrqu.data.pointer = metrics_notification;
12353 wrqu.data.length = scnprintf(metrics_notification,
12354 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
12355 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12356
12357 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12358
12359 EXIT();
12360
12361 return VOS_STATUS_SUCCESS;
12362}
12363
12364/*
12365 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
12366 * 802.11r/LFR metrics reporting function to report preauth completion
12367 * or failure
12368 */
12369VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
12370 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
12371{
12372 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12373 union iwreq_data wrqu;
12374
12375 ENTER();
12376
12377 if (NULL == pAdapter)
12378 {
12379 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12380 return VOS_STATUS_E_FAILURE;
12381 }
12382
12383 /* create the event */
12384 memset(&wrqu, 0, sizeof(wrqu));
12385 memset(metrics_notification, 0, sizeof(metrics_notification));
12386
12387 scnprintf(metrics_notification, sizeof(metrics_notification),
12388 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
12389 MAC_ADDR_ARRAY(pRoamInfo->bssid));
12390
12391 if (1 == preauth_status)
12392 strncat(metrics_notification, " TRUE", 5);
12393 else
12394 strncat(metrics_notification, " FALSE", 6);
12395
12396 wrqu.data.pointer = metrics_notification;
12397 wrqu.data.length = strlen(metrics_notification);
12398
12399 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12400
12401 EXIT();
12402
12403 return VOS_STATUS_SUCCESS;
12404}
12405
12406/*
12407 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
12408 * 802.11r/LFR metrics reporting function to report handover initiation
12409 *
12410 */
12411VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
12412 tCsrRoamInfo *pRoamInfo)
12413{
12414 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
12415 union iwreq_data wrqu;
12416
12417 ENTER();
12418
12419 if (NULL == pAdapter)
12420 {
12421 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
12422 return VOS_STATUS_E_FAILURE;
12423 }
12424
12425 /* create the event */
12426 memset(&wrqu, 0, sizeof(wrqu));
12427 memset(metrics_notification, 0, sizeof(metrics_notification));
12428
12429 wrqu.data.pointer = metrics_notification;
12430 wrqu.data.length = scnprintf(metrics_notification,
12431 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
12432 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
12433
12434 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
12435
12436 EXIT();
12437
12438 return VOS_STATUS_SUCCESS;
12439}
12440#endif
12441
Jeff Johnson295189b2012-06-20 16:38:30 -070012442/*
12443 * FUNCTION: hdd_cfg80211_scan_done_callback
12444 * scanning callback function, called after finishing scan
12445 *
12446 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012447static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070012448 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
12449{
12450 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012451 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070012452 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012453 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012454 struct cfg80211_scan_request *req = NULL;
12455 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012456 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012457 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012458 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012459 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012460
12461 ENTER();
12462
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012463 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053012464 if (NULL == pHddCtx) {
12465 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012466 goto allow_suspend;
12467 }
12468
12469 pScanInfo = &pHddCtx->scan_info;
12470
Jeff Johnson295189b2012-06-20 16:38:30 -070012471 hddLog(VOS_TRACE_LEVEL_INFO,
12472 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080012473 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012474 __func__, halHandle, pContext, (int) scanId, (int) status);
12475
Kiet Lamac06e2c2013-10-23 16:25:07 +053012476 pScanInfo->mScanPendingCounter = 0;
12477
Jeff Johnson295189b2012-06-20 16:38:30 -070012478 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012479 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070012480 &pScanInfo->scan_req_completion_event,
12481 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012482 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070012483 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012484 hddLog(VOS_TRACE_LEVEL_ERROR,
12485 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070012486 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012487 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012488 }
12489
Yue Maef608272013-04-08 23:09:17 -070012490 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070012491 {
12492 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070012493 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012494 }
12495
12496 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012497 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070012498 {
12499 hddLog(VOS_TRACE_LEVEL_INFO,
12500 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080012501 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070012502 (int) scanId);
12503 }
12504
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012505 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012506 pAdapter);
12507
12508 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012509 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012510
12511
12512 /* If any client wait scan result through WEXT
12513 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012514 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070012515 {
12516 /* The other scan request waiting for current scan finish
12517 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012518 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012519 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012520 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070012521 }
12522 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012523 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070012524 {
12525 struct net_device *dev = pAdapter->dev;
12526 union iwreq_data wrqu;
12527 int we_event;
12528 char *msg;
12529
12530 memset(&wrqu, '\0', sizeof(wrqu));
12531 we_event = SIOCGIWSCAN;
12532 msg = NULL;
12533 wireless_send_event(dev, we_event, &wrqu, msg);
12534 }
12535 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070012536 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012537
12538 /* Get the Scan Req */
12539 req = pAdapter->request;
12540
12541 if (!req)
12542 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012543 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012544 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070012545 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070012546 }
12547
Jeff Johnson295189b2012-06-20 16:38:30 -070012548 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070012549 /* Scan is no longer pending */
12550 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012551
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012552 /* last_scan_timestamp is used to decide if new scan
12553 * is needed or not on station interface. If last station
12554 * scan time and new station scan time is less then
12555 * last_scan_timestamp ; driver will return cached scan.
12556 */
12557 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
12558 {
12559 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
12560
12561 if ( req->n_channels )
12562 {
12563 for (i = 0; i < req->n_channels ; i++ )
12564 {
12565 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
12566 }
12567 /* store no of channel scanned */
12568 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
12569 }
12570
12571 }
12572
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070012573 /*
12574 * cfg80211_scan_done informing NL80211 about completion
12575 * of scanning
12576 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012577 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
12578 {
12579 aborted = true;
12580 }
12581 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080012582 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070012583
Siddharth Bhal76972212014-10-15 16:22:51 +053012584 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
12585 /* Generate new random mac addr for next scan */
12586 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
12587 hdd_processSpoofMacAddrRequest(pHddCtx);
12588 }
12589
Jeff Johnsone7245742012-09-05 17:12:55 -070012590allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012591 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012592 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012593
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012594 /* Acquire wakelock to handle the case where APP's tries to suspend
12595 * immediatly after the driver gets connect request(i.e after scan)
12596 * from supplicant, this result in app's is suspending and not able
12597 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012598 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070012599
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012600#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053012601 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070012602#endif
12603
Jeff Johnson295189b2012-06-20 16:38:30 -070012604 EXIT();
12605 return 0;
12606}
12607
12608/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053012609 * FUNCTION: hdd_isConnectionInProgress
12610 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012611 *
12612 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012613v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012614{
12615 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
12616 hdd_station_ctx_t *pHddStaCtx = NULL;
12617 hdd_adapter_t *pAdapter = NULL;
12618 VOS_STATUS status = 0;
12619 v_U8_t staId = 0;
12620 v_U8_t *staMac = NULL;
12621
c_hpothu9b781ba2013-12-30 20:57:45 +053012622 if (TRUE == pHddCtx->btCoexModeSet)
12623 {
12624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053012625 FL("BTCoex Mode operation in progress"));
12626 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053012627 }
12628
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012629 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
12630
12631 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
12632 {
12633 pAdapter = pAdapterNode->pAdapter;
12634
12635 if( pAdapter )
12636 {
12637 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012638 "%s: Adapter with device mode %s (%d) exists",
12639 __func__, hdd_device_modetoString(pAdapter->device_mode),
12640 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012641 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053012642 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12643 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
12644 (eConnectionState_Connecting ==
12645 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
12646 {
12647 hddLog(VOS_TRACE_LEVEL_ERROR,
12648 "%s: %p(%d) Connection is in progress", __func__,
12649 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12650 return VOS_TRUE;
12651 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012652 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053012653 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012654 {
12655 hddLog(VOS_TRACE_LEVEL_ERROR,
12656 "%s: %p(%d) Reassociation is in progress", __func__,
12657 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
12658 return VOS_TRUE;
12659 }
12660 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012661 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
12662 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012663 {
12664 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12665 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012666 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012667 {
12668 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
12669 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012670 "%s: client " MAC_ADDRESS_STR
12671 " is in the middle of WPS/EAPOL exchange.", __func__,
12672 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012673 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012674 }
12675 }
12676 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
12677 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
12678 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012679 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
12680 ptSapContext pSapCtx = NULL;
12681 pSapCtx = VOS_GET_SAP_CB(pVosContext);
12682 if(pSapCtx == NULL){
12683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12684 FL("psapCtx is NULL"));
12685 return VOS_FALSE;
12686 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012687 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
12688 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012689 if ((pSapCtx->aStaInfo[staId].isUsed) &&
12690 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012691 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053012692 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012693
12694 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080012695 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
12696 "middle of WPS/EAPOL exchange.", __func__,
12697 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053012698 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012699 }
12700 }
12701 }
12702 }
12703 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
12704 pAdapterNode = pNext;
12705 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053012706 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012707}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012708
12709/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012710 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070012711 * this scan respond to scan trigger and update cfg80211 scan database
12712 * later, scan dump command can be used to recieve scan results
12713 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012714int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080012715#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12716 struct net_device *dev,
12717#endif
12718 struct cfg80211_scan_request *request)
12719{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012720 hdd_adapter_t *pAdapter = NULL;
12721 hdd_context_t *pHddCtx = NULL;
12722 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012723 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012724 tCsrScanRequest scanRequest;
12725 tANI_U8 *channelList = NULL, i;
12726 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012727 int status;
12728 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012729 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012730 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053012731 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053012732 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053012733 v_S7_t rssi=0;
12734 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012735
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012736#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
12737 struct net_device *dev = NULL;
12738 if (NULL == request)
12739 {
12740 hddLog(VOS_TRACE_LEVEL_ERROR,
12741 "%s: scan req param null", __func__);
12742 return -EINVAL;
12743 }
12744 dev = request->wdev->netdev;
12745#endif
12746
12747 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
12748 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
12749 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12750
Jeff Johnson295189b2012-06-20 16:38:30 -070012751 ENTER();
12752
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012753 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
12754 __func__, hdd_device_modetoString(pAdapter->device_mode),
12755 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012756
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012757 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012758 if (0 != status)
12759 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012760 return status;
12761 }
12762
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012763 if (NULL == pwextBuf)
12764 {
12765 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
12766 __func__);
12767 return -EIO;
12768 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012769 cfg_param = pHddCtx->cfg_ini;
12770 pScanInfo = &pHddCtx->scan_info;
12771
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053012772 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12773 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
12774 {
12775 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
12776 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
12777 }
12778
Jeff Johnson295189b2012-06-20 16:38:30 -070012779#ifdef WLAN_BTAMP_FEATURE
12780 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012781 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070012782 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080012783 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012784 "%s: No scanning when AMP is on", __func__);
12785 return -EOPNOTSUPP;
12786 }
12787#endif
12788 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012789 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070012790 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012791 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012792 "%s: Not scanning on device_mode = %s (%d)",
12793 __func__, hdd_device_modetoString(pAdapter->device_mode),
12794 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012795 return -EOPNOTSUPP;
12796 }
12797
12798 if (TRUE == pScanInfo->mScanPending)
12799 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053012800 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
12801 {
12802 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
12803 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012804 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070012805 }
12806
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053012807 // Don't allow scan if PNO scan is going on.
12808 if (pHddCtx->isPnoEnable)
12809 {
12810 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12811 FL("pno scan in progress"));
12812 return -EBUSY;
12813 }
12814
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012815 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070012816 //Channel and action frame is pending
12817 //Otherwise Cancel Remain On Channel and allow Scan
12818 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080012819 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070012820 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053012821 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070012822 return -EBUSY;
12823 }
12824
Jeff Johnson295189b2012-06-20 16:38:30 -070012825 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
12826 {
12827 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080012828 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012829 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012830 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012831 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
12832 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012833 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012834 "%s: MAX TM Level Scan not allowed", __func__);
12835 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012836 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070012837 }
12838 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
12839
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012840 /* Check if scan is allowed at this point of time.
12841 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053012842 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080012843 {
12844 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
12845 return -EBUSY;
12846 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012847
Jeff Johnson295189b2012-06-20 16:38:30 -070012848 vos_mem_zero( &scanRequest, sizeof(scanRequest));
12849
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012850 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
12851 * Becasue of this, driver is assuming that this is not wildcard scan and so
12852 * is not aging out the scan results.
12853 */
12854 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070012855 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012856 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070012857 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012858
12859 if ((request->ssids) && (0 < request->n_ssids))
12860 {
12861 tCsrSSIDInfo *SsidInfo;
12862 int j;
12863 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
12864 /* Allocate num_ssid tCsrSSIDInfo structure */
12865 SsidInfo = scanRequest.SSIDs.SSIDList =
12866 ( tCsrSSIDInfo *)vos_mem_malloc(
12867 request->n_ssids*sizeof(tCsrSSIDInfo));
12868
12869 if(NULL == scanRequest.SSIDs.SSIDList)
12870 {
12871 hddLog(VOS_TRACE_LEVEL_ERROR,
12872 "%s: memory alloc failed SSIDInfo buffer", __func__);
12873 return -ENOMEM;
12874 }
12875
12876 /* copy all the ssid's and their length */
12877 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
12878 {
12879 /* get the ssid length */
12880 SsidInfo->SSID.length = request->ssids[j].ssid_len;
12881 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
12882 SsidInfo->SSID.length);
12883 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
12884 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
12885 j, SsidInfo->SSID.ssId);
12886 }
12887 /* set the scan type to active */
12888 scanRequest.scanType = eSIR_ACTIVE_SCAN;
12889 }
12890 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070012891 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053012892 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12893 TRACE_CODE_HDD_CFG80211_SCAN,
12894 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070012895 /* set the scan type to active */
12896 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070012897 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012898 else
12899 {
12900 /*Set the scan type to default type, in this case it is ACTIVE*/
12901 scanRequest.scanType = pScanInfo->scan_mode;
12902 }
12903 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
12904 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070012905
12906 /* set BSSType to default type */
12907 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
12908
12909 /*TODO: scan the requested channels only*/
12910
12911 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012912 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070012913 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012914 hddLog(VOS_TRACE_LEVEL_WARN,
12915 "No of Scan Channels exceeded limit: %d", request->n_channels);
12916 request->n_channels = MAX_CHANNEL;
12917 }
12918
12919 hddLog(VOS_TRACE_LEVEL_INFO,
12920 "No of Scan Channels: %d", request->n_channels);
12921
12922
12923 if( request->n_channels )
12924 {
12925 char chList [(request->n_channels*5)+1];
12926 int len;
12927 channelList = vos_mem_malloc( request->n_channels );
12928 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053012929 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012930 hddLog(VOS_TRACE_LEVEL_ERROR,
12931 "%s: memory alloc failed channelList", __func__);
12932 status = -ENOMEM;
12933 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053012934 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012935
12936 for( i = 0, len = 0; i < request->n_channels ; i++ )
12937 {
12938 channelList[i] = request->channels[i]->hw_value;
12939 len += snprintf(chList+len, 5, "%d ", channelList[i]);
12940 }
12941
Nirav Shah20ac06f2013-12-12 18:14:06 +053012942 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012943 "Channel-List: %s ", chList);
12944 }
c_hpothu53512302014-04-15 18:49:53 +053012945
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012946 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
12947 scanRequest.ChannelInfo.ChannelList = channelList;
12948
12949 /* set requestType to full scan */
12950 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
12951
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012952 /* if there is back to back scan happening in driver with in
12953 * nDeferScanTimeInterval interval driver should defer new scan request
12954 * and should provide last cached scan results instead of new channel list.
12955 * This rule is not applicable if scan is p2p scan.
12956 * This condition will work only in case when last request no of channels
12957 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053012958 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053012959 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012960 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012961
Sushant Kaushik86592172015-04-27 16:35:03 +053012962 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
12963 /* if wps ie is NULL , then only defer scan */
12964 if ( pWpsIe == NULL &&
12965 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053012966 {
12967 if ( pScanInfo->last_scan_timestamp !=0 &&
12968 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
12969 {
12970 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
12971 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
12972 vos_mem_compare(pScanInfo->last_scan_channelList,
12973 channelList, pScanInfo->last_scan_numChannels))
12974 {
12975 hddLog(VOS_TRACE_LEVEL_WARN,
12976 " New and old station scan time differ is less then %u",
12977 pHddCtx->cfg_ini->nDeferScanTimeInterval);
12978
12979 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012980 pAdapter);
12981
Agarwal Ashish57e84372014-12-05 18:26:53 +053012982 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053012983 "Return old cached scan as all channels and no of channels are same");
12984
Agarwal Ashish57e84372014-12-05 18:26:53 +053012985 if (0 > ret)
12986 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012987
Agarwal Ashish57e84372014-12-05 18:26:53 +053012988 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053012989
12990 status = eHAL_STATUS_SUCCESS;
12991 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053012992 }
12993 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053012994 }
12995
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053012996 /* Flush the scan results(only p2p beacons) for STA scan and P2P
12997 * search (Flush on both full scan and social scan but not on single
12998 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
12999 */
13000
13001 /* Supplicant does single channel scan after 8-way handshake
13002 * and in that case driver shoudnt flush scan results. If
13003 * driver flushes the scan results here and unfortunately if
13004 * the AP doesnt respond to our probe req then association
13005 * fails which is not desired
13006 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013007 if ((request->n_ssids == 1)
13008 && (request->ssids != NULL)
13009 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
13010 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013011
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053013012 if( is_p2p_scan ||
13013 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013014 {
13015 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
13016 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
13017 pAdapter->sessionId );
13018 }
13019
13020 if( request->ie_len )
13021 {
13022 /* save this for future association (join requires this) */
13023 /*TODO: Array needs to be converted to dynamic allocation,
13024 * as multiple ie.s can be sent in cfg80211_scan_request structure
13025 * CR 597966
13026 */
13027 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
13028 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
13029 pScanInfo->scanAddIE.length = request->ie_len;
13030
13031 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13032 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
13033 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013034 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013035 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070013036 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013037 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
13038 memcpy( pwextBuf->roamProfile.addIEScan,
13039 request->ie, request->ie_len);
13040 }
13041 else
13042 {
13043 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
13044 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070013045 }
13046
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013047 }
13048 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
13049 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
13050
13051 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
13052 request->ie_len);
13053 if (pP2pIe != NULL)
13054 {
13055#ifdef WLAN_FEATURE_P2P_DEBUG
13056 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
13057 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
13058 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053013059 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013060 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
13061 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13062 "Go nego completed to Connection is started");
13063 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13064 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053013065 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013066 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
13067 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070013068 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013069 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
13070 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
13071 "Disconnected state to Connection is started");
13072 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
13073 "for 4way Handshake");
13074 }
13075#endif
13076
13077 /* no_cck will be set during p2p find to disable 11b rates */
13078 if(TRUE == request->no_cck)
13079 {
13080 hddLog(VOS_TRACE_LEVEL_INFO,
13081 "%s: This is a P2P Search", __func__);
13082 scanRequest.p2pSearch = 1;
13083
13084 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053013085 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013086 /* set requestType to P2P Discovery */
13087 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
13088 }
13089
13090 /*
13091 Skip Dfs Channel in case of P2P Search
13092 if it is set in ini file
13093 */
13094 if(cfg_param->skipDfsChnlInP2pSearch)
13095 {
13096 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013097 }
13098 else
13099 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053013100 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053013101 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013102
Agarwal Ashish4f616132013-12-30 23:32:50 +053013103 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013104 }
13105 }
13106
13107 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
13108
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013109#ifdef FEATURE_WLAN_TDLS
13110 /* if tdls disagree scan right now, return immediately.
13111 tdls will schedule the scan when scan is allowed. (return SUCCESS)
13112 or will reject the scan if any TDLS is in progress. (return -EBUSY)
13113 */
13114 status = wlan_hdd_tdls_scan_callback (pAdapter,
13115 wiphy,
13116#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13117 dev,
13118#endif
13119 request);
13120 if(status <= 0)
13121 {
13122 if(!status)
13123 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
13124 "scan rejected %d", __func__, status);
13125 else
13126 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
13127 __func__, status);
13128
13129 return status;
13130 }
13131#endif
13132
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070013133 /* acquire the wakelock to avoid the apps suspend during the scan. To
13134 * address the following issues.
13135 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
13136 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
13137 * for long time, this result in apps running at full power for long time.
13138 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
13139 * be stuck in full power because of resume BMPS
13140 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013141 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070013142
Nirav Shah20ac06f2013-12-12 18:14:06 +053013143 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
13144 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013145 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
13146 scanRequest.requestType, scanRequest.scanType,
13147 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053013148 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
13149
Siddharth Bhal76972212014-10-15 16:22:51 +053013150 if (pHddCtx->spoofMacAddr.isEnabled)
13151 {
13152 hddLog(VOS_TRACE_LEVEL_INFO,
13153 "%s: MAC Spoofing enabled for current scan", __func__);
13154 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
13155 * to fill TxBds for probe request during current scan
13156 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013157 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053013158 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013159
13160 if(status != VOS_STATUS_SUCCESS)
13161 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013162 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013163 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053013164#ifdef FEATURE_WLAN_TDLS
13165 wlan_hdd_tdls_scan_done_callback(pAdapter);
13166#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053013167 goto free_mem;
13168 }
Siddharth Bhal76972212014-10-15 16:22:51 +053013169 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053013170 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070013171 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013172 pAdapter->sessionId, &scanRequest, &scanId,
13173 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070013174
Jeff Johnson295189b2012-06-20 16:38:30 -070013175 if (eHAL_STATUS_SUCCESS != status)
13176 {
13177 hddLog(VOS_TRACE_LEVEL_ERROR,
13178 "%s: sme_ScanRequest returned error %d", __func__, status);
13179 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013180 if(eHAL_STATUS_RESOURCES == status)
13181 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053013182 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
13183 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070013184 status = -EBUSY;
13185 } else {
13186 status = -EIO;
13187 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053013188 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053013189
13190#ifdef FEATURE_WLAN_TDLS
13191 wlan_hdd_tdls_scan_done_callback(pAdapter);
13192#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013193 goto free_mem;
13194 }
13195
13196 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013197 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070013198 pAdapter->request = request;
13199 pScanInfo->scanId = scanId;
13200
13201 complete(&pScanInfo->scan_req_completion_event);
13202
13203free_mem:
13204 if( scanRequest.SSIDs.SSIDList )
13205 {
13206 vos_mem_free(scanRequest.SSIDs.SSIDList);
13207 }
13208
13209 if( channelList )
13210 vos_mem_free( channelList );
13211
13212 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013213 return status;
13214}
13215
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013216int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
13217#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13218 struct net_device *dev,
13219#endif
13220 struct cfg80211_scan_request *request)
13221{
13222 int ret;
13223
13224 vos_ssr_protect(__func__);
13225 ret = __wlan_hdd_cfg80211_scan(wiphy,
13226#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
13227 dev,
13228#endif
13229 request);
13230 vos_ssr_unprotect(__func__);
13231
13232 return ret;
13233}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013234
13235void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
13236{
13237 v_U8_t iniDot11Mode =
13238 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
13239 eHddDot11Mode hddDot11Mode = iniDot11Mode;
13240
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013241 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
13242 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013243 switch ( iniDot11Mode )
13244 {
13245 case eHDD_DOT11_MODE_AUTO:
13246 case eHDD_DOT11_MODE_11ac:
13247 case eHDD_DOT11_MODE_11ac_ONLY:
13248#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053013249 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
13250 sme_IsFeatureSupportedByFW(DOT11AC) )
13251 hddDot11Mode = eHDD_DOT11_MODE_11ac;
13252 else
13253 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013254#else
13255 hddDot11Mode = eHDD_DOT11_MODE_11n;
13256#endif
13257 break;
13258 case eHDD_DOT11_MODE_11n:
13259 case eHDD_DOT11_MODE_11n_ONLY:
13260 hddDot11Mode = eHDD_DOT11_MODE_11n;
13261 break;
13262 default:
13263 hddDot11Mode = iniDot11Mode;
13264 break;
13265 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013266#ifdef WLAN_FEATURE_AP_HT40_24G
13267 if (operationChannel > SIR_11B_CHANNEL_END)
13268#endif
13269 {
13270 /* This call decides required channel bonding mode */
13271 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013272 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
13273 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053013274 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013275}
13276
Jeff Johnson295189b2012-06-20 16:38:30 -070013277/*
13278 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013279 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070013280 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013281int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013282 const u8 *ssid, size_t ssid_len, const u8 *bssid,
13283 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070013284{
13285 int status = 0;
13286 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080013287 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013288 v_U32_t roamId;
13289 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070013290 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013291 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013292
13293 ENTER();
13294
13295 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080013296 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13297
13298 status = wlan_hdd_validate_context(pHddCtx);
13299 if (status)
13300 {
Yue Mae36e3552014-03-05 17:06:20 -080013301 return status;
13302 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013303
Jeff Johnson295189b2012-06-20 16:38:30 -070013304 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
13305 {
13306 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
13307 return -EINVAL;
13308 }
13309
13310 pRoamProfile = &pWextState->roamProfile;
13311
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013312 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070013313 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013314 hdd_station_ctx_t *pHddStaCtx;
13315 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013316
Siddharth Bhalda0d1622015-04-24 15:47:49 +053013317 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
13318
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013319 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070013320 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
13321 {
13322 /*QoS not enabled in cfg file*/
13323 pRoamProfile->uapsd_mask = 0;
13324 }
13325 else
13326 {
13327 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013328 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070013329 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
13330 }
13331
13332 pRoamProfile->SSIDs.numOfSSIDs = 1;
13333 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
13334 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013335 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070013336 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
13337 ssid, ssid_len);
13338
13339 if (bssid)
13340 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013341 pValidBssid = bssid;
13342 }
13343 else if (bssid_hint)
13344 {
13345 pValidBssid = bssid_hint;
13346 }
13347 if (pValidBssid)
13348 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013349 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013350 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013351 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013352 /* Save BSSID in seperate variable as well, as RoamProfile
13353 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070013354 case of join failure we should send valid BSSID to supplicant
13355 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013356 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070013357 WNI_CFG_BSSID_LEN);
13358 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070013359 else
13360 {
13361 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
13362 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013363
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013364 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
13365 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013366 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
13367 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013368 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013369 /*set gen ie*/
13370 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
13371 /*set auth*/
13372 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
13373 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013374#ifdef FEATURE_WLAN_WAPI
13375 if (pAdapter->wapi_info.nWapiMode)
13376 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013377 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013378 switch (pAdapter->wapi_info.wapiAuthMode)
13379 {
13380 case WAPI_AUTH_MODE_PSK:
13381 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013382 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013383 pAdapter->wapi_info.wapiAuthMode);
13384 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
13385 break;
13386 }
13387 case WAPI_AUTH_MODE_CERT:
13388 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013389 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013390 pAdapter->wapi_info.wapiAuthMode);
13391 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
13392 break;
13393 }
13394 } // End of switch
13395 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
13396 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
13397 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070013398 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013399 pRoamProfile->AuthType.numEntries = 1;
13400 pRoamProfile->EncryptionType.numEntries = 1;
13401 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13402 pRoamProfile->mcEncryptionType.numEntries = 1;
13403 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
13404 }
13405 }
13406#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013407#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013408 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013409 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
13410 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
13411 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053013412 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
13413 sizeof (tSirGtkOffloadParams));
13414 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053013415 }
13416#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013417 pRoamProfile->csrPersona = pAdapter->device_mode;
13418
Jeff Johnson32d95a32012-09-10 13:15:23 -070013419 if( operatingChannel )
13420 {
13421 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
13422 pRoamProfile->ChannelInfo.numOfChannels = 1;
13423 }
Chet Lanctot186b5732013-03-18 10:26:30 -070013424 else
13425 {
13426 pRoamProfile->ChannelInfo.ChannelList = NULL;
13427 pRoamProfile->ChannelInfo.numOfChannels = 0;
13428 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013429 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
13430 {
13431 hdd_select_cbmode(pAdapter,operatingChannel);
13432 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013433
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013434 /*
13435 * Change conn_state to connecting before sme_RoamConnect(),
13436 * because sme_RoamConnect() has a direct path to call
13437 * hdd_smeRoamCallback(), which will change the conn_state
13438 * If direct path, conn_state will be accordingly changed
13439 * to NotConnected or Associated by either
13440 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
13441 * in sme_RoamCallback()
13442 * if sme_RomConnect is to be queued,
13443 * Connecting state will remain until it is completed.
13444 * If connection state is not changed,
13445 * connection state will remain in eConnectionState_NotConnected state.
13446 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
13447 * if conn state is eConnectionState_NotConnected.
13448 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
13449 * informed of connect result indication which is an issue.
13450 */
13451
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013452 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13453 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053013454 {
13455 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013456 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013457 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
13458 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053013459 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013460 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070013461 pAdapter->sessionId, pRoamProfile, &roamId);
13462
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053013463 if ((eHAL_STATUS_SUCCESS != status) &&
13464 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
13465 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013466
13467 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053013468 hddLog(VOS_TRACE_LEVEL_ERROR,
13469 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
13470 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013471 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013472 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080013473 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053013474 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080013475
13476 pRoamProfile->ChannelInfo.ChannelList = NULL;
13477 pRoamProfile->ChannelInfo.numOfChannels = 0;
13478
Jeff Johnson295189b2012-06-20 16:38:30 -070013479 }
13480 else
13481 {
13482 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
13483 return -EINVAL;
13484 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080013485 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013486 return status;
13487}
13488
13489/*
13490 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
13491 * This function is used to set the authentication type (OPEN/SHARED).
13492 *
13493 */
13494static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
13495 enum nl80211_auth_type auth_type)
13496{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013497 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013498 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13499
13500 ENTER();
13501
13502 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013503 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070013504 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013505 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013506 hddLog(VOS_TRACE_LEVEL_INFO,
13507 "%s: set authentication type to AUTOSWITCH", __func__);
13508 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
13509 break;
13510
13511 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070013512#ifdef WLAN_FEATURE_VOWIFI_11R
13513 case NL80211_AUTHTYPE_FT:
13514#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013515 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013516 "%s: set authentication type to OPEN", __func__);
13517 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
13518 break;
13519
13520 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013521 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013522 "%s: set authentication type to SHARED", __func__);
13523 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
13524 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013525#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013526 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013527 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070013528 "%s: set authentication type to CCKM WPA", __func__);
13529 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
13530 break;
13531#endif
13532
13533
13534 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013535 hddLog(VOS_TRACE_LEVEL_ERROR,
13536 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013537 auth_type);
13538 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
13539 return -EINVAL;
13540 }
13541
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013542 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013543 pHddStaCtx->conn_info.authType;
13544 return 0;
13545}
13546
13547/*
13548 * FUNCTION: wlan_hdd_set_akm_suite
13549 * This function is used to set the key mgmt type(PSK/8021x).
13550 *
13551 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013552static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013553 u32 key_mgmt
13554 )
13555{
13556 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13557 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053013558 /* Should be in ieee802_11_defs.h */
13559#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
13560#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070013561 /*set key mgmt type*/
13562 switch(key_mgmt)
13563 {
13564 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053013565 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013566#ifdef WLAN_FEATURE_VOWIFI_11R
13567 case WLAN_AKM_SUITE_FT_PSK:
13568#endif
13569 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070013570 __func__);
13571 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
13572 break;
13573
13574 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053013575 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053013576#ifdef WLAN_FEATURE_VOWIFI_11R
13577 case WLAN_AKM_SUITE_FT_8021X:
13578#endif
13579 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070013580 __func__);
13581 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13582 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013583#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013584#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
13585#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
13586 case WLAN_AKM_SUITE_CCKM:
13587 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
13588 __func__);
13589 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
13590 break;
13591#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070013592#ifndef WLAN_AKM_SUITE_OSEN
13593#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
13594 case WLAN_AKM_SUITE_OSEN:
13595 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
13596 __func__);
13597 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
13598 break;
13599#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013600
13601 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013602 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013603 __func__, key_mgmt);
13604 return -EINVAL;
13605
13606 }
13607 return 0;
13608}
13609
13610/*
13611 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013612 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070013613 * (NONE/WEP40/WEP104/TKIP/CCMP).
13614 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013615static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
13616 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070013617 bool ucast
13618 )
13619{
13620 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013621 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013622 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13623
13624 ENTER();
13625
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013626 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013627 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053013628 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070013629 __func__, cipher);
13630 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13631 }
13632 else
13633 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013634
Jeff Johnson295189b2012-06-20 16:38:30 -070013635 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013636 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070013637 {
13638 case IW_AUTH_CIPHER_NONE:
13639 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13640 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013641
Jeff Johnson295189b2012-06-20 16:38:30 -070013642 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013643 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070013644 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013645
Jeff Johnson295189b2012-06-20 16:38:30 -070013646 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053013647 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070013648 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013649
Jeff Johnson295189b2012-06-20 16:38:30 -070013650 case WLAN_CIPHER_SUITE_TKIP:
13651 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
13652 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013653
Jeff Johnson295189b2012-06-20 16:38:30 -070013654 case WLAN_CIPHER_SUITE_CCMP:
13655 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13656 break;
13657#ifdef FEATURE_WLAN_WAPI
13658 case WLAN_CIPHER_SUITE_SMS4:
13659 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
13660 break;
13661#endif
13662
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080013663#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070013664 case WLAN_CIPHER_SUITE_KRK:
13665 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
13666 break;
13667#endif
13668 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013669 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013670 __func__, cipher);
13671 return -EOPNOTSUPP;
13672 }
13673 }
13674
13675 if (ucast)
13676 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013677 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013678 __func__, encryptionType);
13679 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13680 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013681 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013682 encryptionType;
13683 }
13684 else
13685 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013686 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013687 __func__, encryptionType);
13688 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
13689 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
13690 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
13691 }
13692
13693 return 0;
13694}
13695
13696
13697/*
13698 * FUNCTION: wlan_hdd_cfg80211_set_ie
13699 * This function is used to parse WPA/RSN IE's.
13700 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013701int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013702#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13703 const u8 *ie,
13704#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013705 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013706#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013707 size_t ie_len
13708 )
13709{
13710 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013711#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13712 const u8 *genie = ie;
13713#else
Jeff Johnson295189b2012-06-20 16:38:30 -070013714 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013715#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013716 v_U16_t remLen = ie_len;
13717#ifdef FEATURE_WLAN_WAPI
13718 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
13719 u16 *tmp;
13720 v_U16_t akmsuiteCount;
13721 int *akmlist;
13722#endif
13723 ENTER();
13724
13725 /* clear previous assocAddIE */
13726 pWextState->assocAddIE.length = 0;
13727 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013728 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013729
13730 while (remLen >= 2)
13731 {
13732 v_U16_t eLen = 0;
13733 v_U8_t elementId;
13734 elementId = *genie++;
13735 eLen = *genie++;
13736 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013737
Arif Hussain6d2a3322013-11-17 19:50:10 -080013738 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070013739 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013740
13741 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070013742 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013743 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013744 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 -070013745 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013746 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013747 "%s: Invalid WPA IE", __func__);
13748 return -EINVAL;
13749 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013750 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070013751 {
13752 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013753 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013754 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013755
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013756 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013757 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013758 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
13759 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013760 VOS_ASSERT(0);
13761 return -ENOMEM;
13762 }
13763 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
13764 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13765 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013766
Jeff Johnson295189b2012-06-20 16:38:30 -070013767 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
13768 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13769 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13770 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013771 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
13772 {
Jeff Johnson295189b2012-06-20 16:38:30 -070013773 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
13774 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
13775 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
13776 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
13777 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
13778 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013779 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053013780 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070013781 {
13782 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013783 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013784 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013785
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013786 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013787 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013788 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13789 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013790 VOS_ASSERT(0);
13791 return -ENOMEM;
13792 }
13793 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
13794 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13795 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013796
Jeff Johnson295189b2012-06-20 16:38:30 -070013797 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13798 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13799 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013800#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013801 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
13802 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013803 /*Consider WFD IE, only for P2P Client */
13804 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
13805 {
13806 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013807 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070013808 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013809
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013810 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013811 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013812 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13813 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070013814 VOS_ASSERT(0);
13815 return -ENOMEM;
13816 }
13817 // WFD IE is saved to Additional IE ; it should be accumulated to handle
13818 // WPS IE + P2P IE + WFD IE
13819 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13820 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013821
Jeff Johnson295189b2012-06-20 16:38:30 -070013822 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13823 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13824 }
13825#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013826 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013827 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013828 HS20_OUI_TYPE_SIZE)) )
13829 {
13830 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013831 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013832 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013833
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013834 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013835 {
Jeff Johnson902c9832012-12-10 14:28:09 -080013836 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13837 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013838 VOS_ASSERT(0);
13839 return -ENOMEM;
13840 }
13841 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13842 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013843
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070013844 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13845 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13846 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013847 /* Appending OSEN Information Element in Assiciation Request */
13848 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
13849 OSEN_OUI_TYPE_SIZE)) )
13850 {
13851 v_U16_t curAddIELen = pWextState->assocAddIE.length;
13852 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
13853 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013854
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053013855 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070013856 {
13857 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
13858 "Need bigger buffer space");
13859 VOS_ASSERT(0);
13860 return -ENOMEM;
13861 }
13862 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
13863 pWextState->assocAddIE.length += eLen + 2;
13864
13865 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
13866 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
13867 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
13868 }
13869
Abhishek Singh4322e622015-06-10 15:42:54 +053013870 /* Update only for WPA IE */
13871 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
13872 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070013873
13874 /* populating as ADDIE in beacon frames */
13875 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013876 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070013877 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
13878 {
13879 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
13880 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
13881 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
13882 {
13883 hddLog(LOGE,
13884 "Coldn't pass "
13885 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
13886 }
13887 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
13888 else
13889 hddLog(LOGE,
13890 "Could not pass on "
13891 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
13892
13893 /* IBSS mode doesn't contain params->proberesp_ies still
13894 beaconIE's need to be populated in probe response frames */
13895 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
13896 {
13897 u16 rem_probe_resp_ie_len = eLen + 2;
13898 u8 probe_rsp_ie_len[3] = {0};
13899 u8 counter = 0;
13900
13901 /* Check Probe Resp Length if it is greater then 255 then
13902 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
13903 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
13904 not able Store More then 255 bytes into One Variable */
13905
13906 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
13907 {
13908 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
13909 {
13910 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
13911 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
13912 }
13913 else
13914 {
13915 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
13916 rem_probe_resp_ie_len = 0;
13917 }
13918 }
13919
13920 rem_probe_resp_ie_len = 0;
13921
13922 if (probe_rsp_ie_len[0] > 0)
13923 {
13924 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
13925 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
13926 (tANI_U8*)(genie - 2),
13927 probe_rsp_ie_len[0], NULL,
13928 eANI_BOOLEAN_FALSE)
13929 == eHAL_STATUS_FAILURE)
13930 {
13931 hddLog(LOGE,
13932 "Could not pass"
13933 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
13934 }
13935 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
13936 }
13937
13938 if (probe_rsp_ie_len[1] > 0)
13939 {
13940 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
13941 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
13942 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
13943 probe_rsp_ie_len[1], NULL,
13944 eANI_BOOLEAN_FALSE)
13945 == eHAL_STATUS_FAILURE)
13946 {
13947 hddLog(LOGE,
13948 "Could not pass"
13949 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
13950 }
13951 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
13952 }
13953
13954 if (probe_rsp_ie_len[2] > 0)
13955 {
13956 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
13957 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
13958 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
13959 probe_rsp_ie_len[2], NULL,
13960 eANI_BOOLEAN_FALSE)
13961 == eHAL_STATUS_FAILURE)
13962 {
13963 hddLog(LOGE,
13964 "Could not pass"
13965 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
13966 }
13967 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
13968 }
13969
13970 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
13971 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
13972 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
13973 {
13974 hddLog(LOGE,
13975 "Could not pass"
13976 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
13977 }
13978 }
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070013979 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070013980 break;
13981 case DOT11F_EID_RSN:
13982 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
13983 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
13984 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
13985 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
13986 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
13987 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053013988
13989 /* Appending Extended Capabilities with Interworking bit set
13990 * in Assoc Req.
13991 *
13992 * In assoc req this EXT Cap will only be taken into account if
13993 * interworkingService bit is set to 1. Currently
13994 * driver is only interested in interworkingService capability
13995 * from supplicant. If in future any other EXT Cap info is
13996 * required from supplicat, it needs to be handled while
13997 * sending Assoc Req in LIM.
13998 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070013999 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014000 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014001 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014002 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014003 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014004
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053014005 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014006 {
Jeff Johnson902c9832012-12-10 14:28:09 -080014007 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
14008 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014009 VOS_ASSERT(0);
14010 return -ENOMEM;
14011 }
14012 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
14013 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014014
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014015 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
14016 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
14017 break;
14018 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014019#ifdef FEATURE_WLAN_WAPI
14020 case WLAN_EID_WAPI:
14021 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070014022 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070014023 pAdapter->wapi_info.nWapiMode);
14024 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014025 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070014026 akmsuiteCount = WPA_GET_LE16(tmp);
14027 tmp = tmp + 1;
14028 akmlist = (int *)(tmp);
14029 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
14030 {
14031 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
14032 }
14033 else
14034 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014035 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070014036 VOS_ASSERT(0);
14037 return -EINVAL;
14038 }
14039
14040 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
14041 {
14042 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014043 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014044 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014045 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014046 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014047 {
Jeff Johnson295189b2012-06-20 16:38:30 -070014048 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070014049 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014050 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
14051 }
14052 break;
14053#endif
14054 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014055 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014056 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070014057 /* when Unknown IE is received we should break and continue
14058 * to the next IE in the buffer instead we were returning
14059 * so changing this to break */
14060 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070014061 }
14062 genie += eLen;
14063 remLen -= eLen;
14064 }
14065 EXIT();
14066 return 0;
14067}
14068
14069/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014070 * FUNCTION: hdd_isWPAIEPresent
14071 * Parse the received IE to find the WPA IE
14072 *
14073 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014074static bool hdd_isWPAIEPresent(
14075#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
14076 const u8 *ie,
14077#else
14078 u8 *ie,
14079#endif
14080 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053014081{
14082 v_U8_t eLen = 0;
14083 v_U16_t remLen = ie_len;
14084 v_U8_t elementId = 0;
14085
14086 while (remLen >= 2)
14087 {
14088 elementId = *ie++;
14089 eLen = *ie++;
14090 remLen -= 2;
14091 if (eLen > remLen)
14092 {
14093 hddLog(VOS_TRACE_LEVEL_ERROR,
14094 "%s: IE length is wrong %d", __func__, eLen);
14095 return FALSE;
14096 }
14097 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
14098 {
14099 /* OUI - 0x00 0X50 0XF2
14100 WPA Information Element - 0x01
14101 WPA version - 0x01*/
14102 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
14103 return TRUE;
14104 }
14105 ie += eLen;
14106 remLen -= eLen;
14107 }
14108 return FALSE;
14109}
14110
14111/*
Jeff Johnson295189b2012-06-20 16:38:30 -070014112 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014113 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014114 * parameters during connect operation.
14115 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014116int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014117 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014118 )
Jeff Johnson295189b2012-06-20 16:38:30 -070014119{
14120 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014121 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014122 ENTER();
14123
14124 /*set wpa version*/
14125 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
14126
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014127 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014128 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053014129 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070014130 {
14131 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14132 }
14133 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
14134 {
14135 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14136 }
14137 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014138
14139 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070014140 pWextState->wpaVersion);
14141
14142 /*set authentication type*/
14143 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
14144
14145 if (0 > status)
14146 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014147 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014148 "%s: failed to set authentication type ", __func__);
14149 return status;
14150 }
14151
14152 /*set key mgmt type*/
14153 if (req->crypto.n_akm_suites)
14154 {
14155 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
14156 if (0 > status)
14157 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014158 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070014159 __func__);
14160 return status;
14161 }
14162 }
14163
14164 /*set pairwise cipher type*/
14165 if (req->crypto.n_ciphers_pairwise)
14166 {
14167 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
14168 req->crypto.ciphers_pairwise[0], true);
14169 if (0 > status)
14170 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014171 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014172 "%s: failed to set unicast cipher type", __func__);
14173 return status;
14174 }
14175 }
14176 else
14177 {
14178 /*Reset previous cipher suite to none*/
14179 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
14180 if (0 > status)
14181 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014182 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014183 "%s: failed to set unicast cipher type", __func__);
14184 return status;
14185 }
14186 }
14187
14188 /*set group cipher type*/
14189 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
14190 false);
14191
14192 if (0 > status)
14193 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014194 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070014195 __func__);
14196 return status;
14197 }
14198
Chet Lanctot186b5732013-03-18 10:26:30 -070014199#ifdef WLAN_FEATURE_11W
14200 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
14201#endif
14202
Jeff Johnson295189b2012-06-20 16:38:30 -070014203 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
14204 if (req->ie_len)
14205 {
14206 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
14207 if ( 0 > status)
14208 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014209 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014210 __func__);
14211 return status;
14212 }
14213 }
14214
14215 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014216 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014217 {
14218 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
14219 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
14220 )
14221 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014222 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070014223 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
14224 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014225 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070014226 __func__);
14227 return -EOPNOTSUPP;
14228 }
14229 else
14230 {
14231 u8 key_len = req->key_len;
14232 u8 key_idx = req->key_idx;
14233
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014234 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070014235 && (CSR_MAX_NUM_KEY > key_idx)
14236 )
14237 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014238 hddLog(VOS_TRACE_LEVEL_INFO,
14239 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014240 __func__, key_idx, key_len);
14241 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014242 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070014243 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014244 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070014245 (u8)key_len;
14246 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
14247 }
14248 }
14249 }
14250 }
14251
14252 return status;
14253}
14254
14255/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014256 * FUNCTION: wlan_hdd_try_disconnect
14257 * This function is used to disconnect from previous
14258 * connection
14259 */
14260static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
14261{
14262 long ret = 0;
14263 hdd_station_ctx_t *pHddStaCtx;
14264 eMib_dot11DesiredBssType connectedBssType;
14265
14266 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14267
14268 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
14269
14270 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
14271 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
14272 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
14273 {
14274 /* Issue disconnect to CSR */
14275 INIT_COMPLETION(pAdapter->disconnect_comp_var);
14276 if( eHAL_STATUS_SUCCESS ==
14277 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
14278 pAdapter->sessionId,
14279 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
14280 {
14281 ret = wait_for_completion_interruptible_timeout(
14282 &pAdapter->disconnect_comp_var,
14283 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
14284 if (0 >= ret)
14285 {
14286 hddLog(LOGE, FL("Failed to receive disconnect event"));
14287 return -EALREADY;
14288 }
14289 }
14290 }
14291 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
14292 {
14293 ret = wait_for_completion_interruptible_timeout(
14294 &pAdapter->disconnect_comp_var,
14295 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
14296 if (0 >= ret)
14297 {
14298 hddLog(LOGE, FL("Failed to receive disconnect event"));
14299 return -EALREADY;
14300 }
14301 }
14302
14303 return 0;
14304}
14305
14306/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053014307 * FUNCTION: __wlan_hdd_cfg80211_connect
14308 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070014309 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014310static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014311 struct net_device *ndev,
14312 struct cfg80211_connect_params *req
14313 )
14314{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014315 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014316 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014317 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053014318 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014319
14320 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014321
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014322 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14323 TRACE_CODE_HDD_CFG80211_CONNECT,
14324 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014325 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014326 "%s: device_mode = %s (%d)", __func__,
14327 hdd_device_modetoString(pAdapter->device_mode),
14328 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014329
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014330 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014331 if (!pHddCtx)
14332 {
14333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14334 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053014335 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080014336 }
14337
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014338 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014339 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014340 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014341 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014342 }
14343
Agarwal Ashish51325b52014-06-16 16:50:49 +053014344 if (vos_max_concurrent_connections_reached()) {
14345 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14346 return -ECONNREFUSED;
14347 }
14348
Jeff Johnson295189b2012-06-20 16:38:30 -070014349#ifdef WLAN_BTAMP_FEATURE
14350 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014351 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070014352 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014353 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014354 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080014355 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070014356 }
14357#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014358
14359 //If Device Mode is Station Concurrent Sessions Exit BMps
14360 //P2P Mode will be taken care in Open/close adapter
14361 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053014362 (vos_concurrent_open_sessions_running())) {
14363 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
14364 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014365 }
14366
14367 /*Try disconnecting if already in connected state*/
14368 status = wlan_hdd_try_disconnect(pAdapter);
14369 if ( 0 > status)
14370 {
14371 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14372 " connection"));
14373 return -EALREADY;
14374 }
14375
Jeff Johnson295189b2012-06-20 16:38:30 -070014376 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014377 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070014378
14379 if ( 0 > status)
14380 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014381 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070014382 __func__);
14383 return status;
14384 }
Mohit Khanna765234a2012-09-11 15:08:35 -070014385 if ( req->channel )
14386 {
14387 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
14388 req->ssid_len, req->bssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014389 req->bssid_hint,
Mohit Khanna765234a2012-09-11 15:08:35 -070014390 req->channel->hw_value);
14391 }
14392 else
14393 {
14394 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014395 req->ssid_len, req->bssid,
14396 req->bssid_hint, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070014397 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014398
Sushant Kaushikd7083982015-03-18 14:33:24 +053014399 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014400 {
14401 //ReEnable BMPS if disabled
14402 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
14403 (NULL != pHddCtx))
14404 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053014405 if (pHddCtx->hdd_wlan_suspended)
14406 {
14407 hdd_set_pwrparams(pHddCtx);
14408 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014409 //ReEnable Bmps and Imps back
14410 hdd_enable_bmps_imps(pHddCtx);
14411 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053014412 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070014413 return status;
14414 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014415 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014416 EXIT();
14417 return status;
14418}
14419
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014420static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
14421 struct net_device *ndev,
14422 struct cfg80211_connect_params *req)
14423{
14424 int ret;
14425 vos_ssr_protect(__func__);
14426 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
14427 vos_ssr_unprotect(__func__);
14428
14429 return ret;
14430}
Jeff Johnson295189b2012-06-20 16:38:30 -070014431
14432/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014433 * FUNCTION: wlan_hdd_disconnect
14434 * This function is used to issue a disconnect request to SME
14435 */
14436int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
14437{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014438 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014439 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014440 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014441 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014442
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014443 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014444
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014445 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014446 if (0 != status)
14447 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014448 return status;
14449 }
14450
Sushant Kaushikb4834d22015-07-15 15:29:05 +053014451 if (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)
14452 {
14453 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
14454 pAdapter->sessionId);
14455 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014456 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014457
Agarwal Ashish47d18112014-08-04 19:55:07 +053014458 /* Need to apply spin lock before decreasing active sessions
14459 * as there can be chance for double decrement if context switch
14460 * Calls hdd_DisConnectHandler.
14461 */
14462
14463 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014464 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
14465 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014466 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
14467 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053014468 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
14469 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053014470
Abhishek Singhf4669da2014-05-26 15:07:49 +053014471 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053014472 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
14473
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014474 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014475
Mihir Shete182a0b22014-08-18 16:08:48 +053014476 /*
14477 * stop tx queues before deleting STA/BSS context from the firmware.
14478 * tx has to be disabled because the firmware can get busy dropping
14479 * the tx frames after BSS/STA has been deleted and will not send
14480 * back a response resulting in WDI timeout
14481 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053014482 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053014483 netif_tx_disable(pAdapter->dev);
14484 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014485
Mihir Shete182a0b22014-08-18 16:08:48 +053014486 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014487 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
14488 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014489 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
14490 {
14491 hddLog(VOS_TRACE_LEVEL_INFO,
14492 FL("status = %d, already disconnected"),
14493 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014494
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014495 }
14496 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014497 {
14498 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014499 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014500 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014501 result = -EINVAL;
14502 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014503 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014504 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014505 &pAdapter->disconnect_comp_var,
14506 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014507 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014508 {
14509 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014510 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014511 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014512 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014513 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053014514 {
14515 hddLog(VOS_TRACE_LEVEL_ERROR,
14516 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014517 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014518 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014519disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053014520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14521 FL("Set HDD connState to eConnectionState_NotConnected"));
14522 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
14523
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014524 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053014525 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014526}
14527
14528
14529/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014530 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070014531 * This function is used to issue a disconnect request to SME
14532 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014533static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014534 struct net_device *dev,
14535 u16 reason
14536 )
14537{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014538 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014539 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014540 tCsrRoamProfile *pRoamProfile;
14541 hdd_station_ctx_t *pHddStaCtx;
14542 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014543#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014544 tANI_U8 staIdx;
14545#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014546
Jeff Johnson295189b2012-06-20 16:38:30 -070014547 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014548
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053014549 if (!pAdapter) {
14550 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
14551 return -EINVAL;
14552 }
14553
14554 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14555 if (!pHddStaCtx) {
14556 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
14557 return -EINVAL;
14558 }
14559
14560 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14561 status = wlan_hdd_validate_context(pHddCtx);
14562 if (0 != status)
14563 {
14564 return status;
14565 }
14566
14567 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
14568
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014569 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14570 TRACE_CODE_HDD_CFG80211_DISCONNECT,
14571 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014572 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
14573 __func__, hdd_device_modetoString(pAdapter->device_mode),
14574 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014575
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014576 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
14577 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070014578
Jeff Johnson295189b2012-06-20 16:38:30 -070014579 if (NULL != pRoamProfile)
14580 {
14581 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014582 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
14583 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070014584 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014585 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070014586 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014587 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070014588 switch(reason)
14589 {
14590 case WLAN_REASON_MIC_FAILURE:
14591 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
14592 break;
14593
14594 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
14595 case WLAN_REASON_DISASSOC_AP_BUSY:
14596 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
14597 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
14598 break;
14599
14600 case WLAN_REASON_PREV_AUTH_NOT_VALID:
14601 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053014602 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070014603 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
14604 break;
14605
Jeff Johnson295189b2012-06-20 16:38:30 -070014606 default:
14607 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
14608 break;
14609 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014610 pScanInfo = &pHddCtx->scan_info;
14611 if (pScanInfo->mScanPending)
14612 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014613 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014614 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053014615 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053014616 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053014617 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053014618 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014619#ifdef FEATURE_WLAN_TDLS
14620 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014621 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014622 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014623 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
14624 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014625 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014626 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014627 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014629 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080014630 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014631 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053014632 status = sme_DeleteTdlsPeerSta(
14633 WLAN_HDD_GET_HAL_CTX(pAdapter),
14634 pAdapter->sessionId,
14635 mac);
14636 if (status != eHAL_STATUS_SUCCESS) {
14637 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
14638 return -EPERM;
14639 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080014640 }
14641 }
14642#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053014643 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014644 status = wlan_hdd_disconnect(pAdapter, reasonCode);
14645 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070014646 {
14647 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014648 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014649 __func__, (int)status );
14650 return -EINVAL;
14651 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014652 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053014653 else
14654 {
14655 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
14656 "called while in %d state", __func__,
14657 pHddStaCtx->conn_info.connState);
14658 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014659 }
14660 else
14661 {
14662 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
14663 }
14664
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014665 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014666 return status;
14667}
14668
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053014669static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
14670 struct net_device *dev,
14671 u16 reason
14672 )
14673{
14674 int ret;
14675 vos_ssr_protect(__func__);
14676 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
14677 vos_ssr_unprotect(__func__);
14678
14679 return ret;
14680}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053014681
Jeff Johnson295189b2012-06-20 16:38:30 -070014682/*
14683 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014684 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070014685 * settings in IBSS mode.
14686 */
14687static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014688 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070014689 struct cfg80211_ibss_params *params
14690 )
14691{
14692 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014693 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070014694 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
14695 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014696
Jeff Johnson295189b2012-06-20 16:38:30 -070014697 ENTER();
14698
14699 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070014700 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070014701
14702 if (params->ie_len && ( NULL != params->ie) )
14703 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014704 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
14705 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070014706 {
14707 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
14708 encryptionType = eCSR_ENCRYPT_TYPE_AES;
14709 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014710 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070014711 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014712 tDot11fIEWPA dot11WPAIE;
14713 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014714 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014715
Wilson Yang00256342013-10-10 23:13:38 -070014716 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014717 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
14718 params->ie_len, DOT11F_EID_WPA);
14719 if ( NULL != ie )
14720 {
14721 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
14722 // Unpack the WPA IE
14723 //Skip past the EID byte and length byte - and four byte WiFi OUI
14724 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
14725 &ie[2+4],
14726 ie[1] - 4,
14727 &dot11WPAIE);
14728 /*Extract the multicast cipher, the encType for unicast
14729 cipher for wpa-none is none*/
14730 encryptionType =
14731 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
14732 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014733 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070014734
Jeff Johnson295189b2012-06-20 16:38:30 -070014735 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
14736
14737 if (0 > status)
14738 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014739 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070014740 __func__);
14741 return status;
14742 }
14743 }
14744
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014745 pWextState->roamProfile.AuthType.authType[0] =
14746 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070014747 eCSR_AUTH_TYPE_OPEN_SYSTEM;
14748
14749 if (params->privacy)
14750 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014751 /* Security enabled IBSS, At this time there is no information available
14752 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070014753 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014754 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070014755 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014756 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070014757 *enable privacy bit in beacons */
14758
14759 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
14760 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070014761 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
14762 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070014763 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
14764 pWextState->roamProfile.EncryptionType.numEntries = 1;
14765 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070014766 return status;
14767}
14768
14769/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014770 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014771 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070014772 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014773static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014774 struct net_device *dev,
14775 struct cfg80211_ibss_params *params
14776 )
14777{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014778 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070014779 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14780 tCsrRoamProfile *pRoamProfile;
14781 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014782 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14783 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014784 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070014785
14786 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014787
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014788 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14789 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
14790 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014791 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014792 "%s: device_mode = %s (%d)", __func__,
14793 hdd_device_modetoString(pAdapter->device_mode),
14794 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014795
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014796 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014797 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014798 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014799 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014800 }
14801
14802 if (NULL == pWextState)
14803 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014804 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070014805 __func__);
14806 return -EIO;
14807 }
14808
Agarwal Ashish51325b52014-06-16 16:50:49 +053014809 if (vos_max_concurrent_connections_reached()) {
14810 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
14811 return -ECONNREFUSED;
14812 }
14813
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053014814 /*Try disconnecting if already in connected state*/
14815 status = wlan_hdd_try_disconnect(pAdapter);
14816 if ( 0 > status)
14817 {
14818 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
14819 " IBSS connection"));
14820 return -EALREADY;
14821 }
14822
Jeff Johnson295189b2012-06-20 16:38:30 -070014823 pRoamProfile = &pWextState->roamProfile;
14824
14825 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
14826 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014827 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014828 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014829 return -EINVAL;
14830 }
14831
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070014832 /* BSSID is provided by upper layers hence no need to AUTO generate */
14833 if (NULL != params->bssid) {
14834 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
14835 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
14836 hddLog (VOS_TRACE_LEVEL_ERROR,
14837 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
14838 return -EIO;
14839 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014840 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070014841 }
krunal sonie9002db2013-11-25 14:24:17 -080014842 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
14843 {
14844 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
14845 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
14846 {
14847 hddLog (VOS_TRACE_LEVEL_ERROR,
14848 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
14849 return -EIO;
14850 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014851
14852 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080014853 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014854 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080014855 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070014856
Jeff Johnson295189b2012-06-20 16:38:30 -070014857 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070014858 if (NULL !=
14859#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
14860 params->chandef.chan)
14861#else
14862 params->channel)
14863#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014864 {
14865 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014866 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
14867 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
14868 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14869 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014870
14871 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014872 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070014873 ieee80211_frequency_to_channel(
14874#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
14875 params->chandef.chan->center_freq);
14876#else
14877 params->channel->center_freq);
14878#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014879
14880 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
14881 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070014882 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014883 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
14884 __func__);
14885 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070014886 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014887
14888 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070014889 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014890 if (channelNum == validChan[indx])
14891 {
14892 break;
14893 }
14894 }
14895 if (indx >= numChans)
14896 {
14897 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070014898 __func__, channelNum);
14899 return -EINVAL;
14900 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014901 /* Set the Operational Channel */
14902 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
14903 channelNum);
14904 pRoamProfile->ChannelInfo.numOfChannels = 1;
14905 pHddStaCtx->conn_info.operationChannel = channelNum;
14906 pRoamProfile->ChannelInfo.ChannelList =
14907 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070014908 }
14909
14910 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014911 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070014912 if (status < 0)
14913 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014914 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070014915 __func__);
14916 return status;
14917 }
14918
14919 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014920 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053014921 params->ssid_len, params->bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070014922 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070014923
14924 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070014925 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014926
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014927 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014928 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014929}
14930
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014931static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
14932 struct net_device *dev,
14933 struct cfg80211_ibss_params *params
14934 )
14935{
14936 int ret = 0;
14937
14938 vos_ssr_protect(__func__);
14939 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
14940 vos_ssr_unprotect(__func__);
14941
14942 return ret;
14943}
14944
Jeff Johnson295189b2012-06-20 16:38:30 -070014945/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014946 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014947 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070014948 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014949static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070014950 struct net_device *dev
14951 )
14952{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014953 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014954 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
14955 tCsrRoamProfile *pRoamProfile;
14956 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014957 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014958
14959 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014960
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014961 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14962 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
14963 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014964 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014965 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014966 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014967 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014968 }
14969
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053014970 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
14971 hdd_device_modetoString(pAdapter->device_mode),
14972 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070014973 if (NULL == pWextState)
14974 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014975 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070014976 __func__);
14977 return -EIO;
14978 }
14979
14980 pRoamProfile = &pWextState->roamProfile;
14981
14982 /* Issue disconnect only if interface type is set to IBSS */
14983 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
14984 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014985 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070014986 __func__);
14987 return -EINVAL;
14988 }
14989
14990 /* Issue Disconnect request */
14991 INIT_COMPLETION(pAdapter->disconnect_comp_var);
14992 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
14993 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
14994
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014995 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014996 return 0;
14997}
14998
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014999static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
15000 struct net_device *dev
15001 )
15002{
15003 int ret = 0;
15004
15005 vos_ssr_protect(__func__);
15006 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
15007 vos_ssr_unprotect(__func__);
15008
15009 return ret;
15010}
15011
Jeff Johnson295189b2012-06-20 16:38:30 -070015012/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015013 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070015014 * This function is used to set the phy parameters
15015 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
15016 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015017static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070015018 u32 changed)
15019{
15020 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
15021 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015022 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015023
15024 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015025
15026 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015027 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
15028 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015029
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015030 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015031 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015032 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015033 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015034 }
15035
Jeff Johnson295189b2012-06-20 16:38:30 -070015036 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
15037 {
15038 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
15039 WNI_CFG_RTS_THRESHOLD_STAMAX :
15040 wiphy->rts_threshold;
15041
15042 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015043 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070015044 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015045 hddLog(VOS_TRACE_LEVEL_ERROR,
15046 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015047 __func__, rts_threshold);
15048 return -EINVAL;
15049 }
15050
15051 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
15052 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015053 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015054 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015055 hddLog(VOS_TRACE_LEVEL_ERROR,
15056 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015057 __func__, rts_threshold);
15058 return -EIO;
15059 }
15060
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015061 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015062 rts_threshold);
15063 }
15064
15065 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
15066 {
15067 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
15068 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
15069 wiphy->frag_threshold;
15070
15071 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015072 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070015073 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015074 hddLog(VOS_TRACE_LEVEL_ERROR,
15075 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070015076 frag_threshold);
15077 return -EINVAL;
15078 }
15079
15080 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
15081 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015082 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015083 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015084 hddLog(VOS_TRACE_LEVEL_ERROR,
15085 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015086 __func__, frag_threshold);
15087 return -EIO;
15088 }
15089
15090 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
15091 frag_threshold);
15092 }
15093
15094 if ((changed & WIPHY_PARAM_RETRY_SHORT)
15095 || (changed & WIPHY_PARAM_RETRY_LONG))
15096 {
15097 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
15098 wiphy->retry_short :
15099 wiphy->retry_long;
15100
15101 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
15102 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
15103 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015104 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015105 __func__, retry_value);
15106 return -EINVAL;
15107 }
15108
15109 if (changed & WIPHY_PARAM_RETRY_SHORT)
15110 {
15111 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
15112 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015113 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015114 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015115 hddLog(VOS_TRACE_LEVEL_ERROR,
15116 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015117 __func__, retry_value);
15118 return -EIO;
15119 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015120 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015121 __func__, retry_value);
15122 }
15123 else if (changed & WIPHY_PARAM_RETRY_SHORT)
15124 {
15125 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
15126 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015127 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015128 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015129 hddLog(VOS_TRACE_LEVEL_ERROR,
15130 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015131 __func__, retry_value);
15132 return -EIO;
15133 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015134 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070015135 __func__, retry_value);
15136 }
15137 }
15138
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015139 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015140 return 0;
15141}
15142
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015143static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
15144 u32 changed)
15145{
15146 int ret;
15147
15148 vos_ssr_protect(__func__);
15149 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
15150 vos_ssr_unprotect(__func__);
15151
15152 return ret;
15153}
15154
Jeff Johnson295189b2012-06-20 16:38:30 -070015155/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015156 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015157 * This function is used to set the txpower
15158 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015159static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015160#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15161 struct wireless_dev *wdev,
15162#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015163#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015164 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015165#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015166 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070015167#endif
15168 int dbm)
15169{
15170 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015171 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070015172 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
15173 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015174 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015175
15176 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015177
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015178 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15179 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
15180 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015181 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015182 if (0 != status)
15183 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015184 return status;
15185 }
15186
15187 hHal = pHddCtx->hHal;
15188
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015189 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
15190 dbm, ccmCfgSetCallback,
15191 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070015192 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015193 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070015194 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
15195 return -EIO;
15196 }
15197
15198 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
15199 dbm);
15200
15201 switch(type)
15202 {
15203 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
15204 /* Fall through */
15205 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
15206 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
15207 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015208 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
15209 __func__);
15210 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070015211 }
15212 break;
15213 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015214 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070015215 __func__);
15216 return -EOPNOTSUPP;
15217 break;
15218 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015219 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
15220 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070015221 return -EIO;
15222 }
15223
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015224 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015225 return 0;
15226}
15227
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053015228static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
15229#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15230 struct wireless_dev *wdev,
15231#endif
15232#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15233 enum tx_power_setting type,
15234#else
15235 enum nl80211_tx_power_setting type,
15236#endif
15237 int dbm)
15238{
15239 int ret;
15240 vos_ssr_protect(__func__);
15241 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
15242#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15243 wdev,
15244#endif
15245#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
15246 type,
15247#else
15248 type,
15249#endif
15250 dbm);
15251 vos_ssr_unprotect(__func__);
15252
15253 return ret;
15254}
15255
Jeff Johnson295189b2012-06-20 16:38:30 -070015256/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015257 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070015258 * This function is used to read the txpower
15259 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015260static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070015261#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15262 struct wireless_dev *wdev,
15263#endif
15264 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070015265{
15266
15267 hdd_adapter_t *pAdapter;
15268 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015269 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015270
Jeff Johnsone7245742012-09-05 17:12:55 -070015271 ENTER();
15272
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015273 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015274 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015275 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015276 *dbm = 0;
15277 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015278 }
15279
Jeff Johnson295189b2012-06-20 16:38:30 -070015280 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
15281 if (NULL == pAdapter)
15282 {
15283 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
15284 return -ENOENT;
15285 }
15286
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015287 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15288 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
15289 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070015290 wlan_hdd_get_classAstats(pAdapter);
15291 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
15292
Jeff Johnsone7245742012-09-05 17:12:55 -070015293 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015294 return 0;
15295}
15296
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015297static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
15298#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15299 struct wireless_dev *wdev,
15300#endif
15301 int *dbm)
15302{
15303 int ret;
15304
15305 vos_ssr_protect(__func__);
15306 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
15307#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
15308 wdev,
15309#endif
15310 dbm);
15311 vos_ssr_unprotect(__func__);
15312
15313 return ret;
15314}
15315
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015316static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015317#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15318 const u8* mac,
15319#else
15320 u8* mac,
15321#endif
15322 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070015323{
15324 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
15325 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15326 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053015327 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015328
15329 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
15330 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070015331
15332 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
15333 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
15334 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
15335 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
15336 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
15337 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
15338 tANI_U16 maxRate = 0;
15339 tANI_U16 myRate;
15340 tANI_U16 currentRate = 0;
15341 tANI_U8 maxSpeedMCS = 0;
15342 tANI_U8 maxMCSIdx = 0;
15343 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053015344 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070015345 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015346 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015347
Leo Chang6f8870f2013-03-26 18:11:36 -070015348#ifdef WLAN_FEATURE_11AC
15349 tANI_U32 vht_mcs_map;
15350 eDataRate11ACMaxMcs vhtMaxMcs;
15351#endif /* WLAN_FEATURE_11AC */
15352
Jeff Johnsone7245742012-09-05 17:12:55 -070015353 ENTER();
15354
Jeff Johnson295189b2012-06-20 16:38:30 -070015355 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15356 (0 == ssidlen))
15357 {
15358 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
15359 " Invalid ssidlen, %d", __func__, ssidlen);
15360 /*To keep GUI happy*/
15361 return 0;
15362 }
15363
Mukul Sharma811205f2014-07-09 21:07:30 +053015364 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
15365 {
15366 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15367 "%s: Roaming in progress, so unable to proceed this request", __func__);
15368 return 0;
15369 }
15370
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015371 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015372 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015373 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015374 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015375 }
15376
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053015377 wlan_hdd_get_station_stats(pAdapter);
15378 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070015379
Kiet Lam3b17fc82013-09-27 05:24:08 +053015380 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
15381 sinfo->filled |= STATION_INFO_SIGNAL;
15382
c_hpothu09f19542014-05-30 21:53:31 +053015383 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053015384 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
15385 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053015386 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053015387 {
15388 rate_flags = pAdapter->maxRateFlags;
15389 }
c_hpothu44ff4e02014-05-08 00:13:57 +053015390
Jeff Johnson295189b2012-06-20 16:38:30 -070015391 //convert to the UI units of 100kbps
15392 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
15393
15394#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070015395 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 -070015396 sinfo->signal,
15397 pCfg->reportMaxLinkSpeed,
15398 myRate,
15399 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015400 (int) pCfg->linkSpeedRssiMid,
15401 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070015402 (int) rate_flags,
15403 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070015404#endif //LINKSPEED_DEBUG_ENABLED
15405
15406 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
15407 {
15408 // we do not want to necessarily report the current speed
15409 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
15410 {
15411 // report the max possible speed
15412 rssidx = 0;
15413 }
15414 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
15415 {
15416 // report the max possible speed with RSSI scaling
15417 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
15418 {
15419 // report the max possible speed
15420 rssidx = 0;
15421 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015422 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070015423 {
15424 // report middle speed
15425 rssidx = 1;
15426 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015427 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
15428 {
15429 // report middle speed
15430 rssidx = 2;
15431 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015432 else
15433 {
15434 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070015435 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070015436 }
15437 }
15438 else
15439 {
15440 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
15441 hddLog(VOS_TRACE_LEVEL_ERROR,
15442 "%s: Invalid value for reportMaxLinkSpeed: %u",
15443 __func__, pCfg->reportMaxLinkSpeed);
15444 rssidx = 0;
15445 }
15446
15447 maxRate = 0;
15448
15449 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015450 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
15451 OperationalRates, &ORLeng))
15452 {
15453 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15454 /*To keep GUI happy*/
15455 return 0;
15456 }
15457
Jeff Johnson295189b2012-06-20 16:38:30 -070015458 for (i = 0; i < ORLeng; i++)
15459 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015460 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015461 {
15462 /* Validate Rate Set */
15463 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
15464 {
15465 currentRate = supported_data_rate[j].supported_rate[rssidx];
15466 break;
15467 }
15468 }
15469 /* Update MAX rate */
15470 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15471 }
15472
15473 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015474 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
15475 ExtendedRates, &ERLeng))
15476 {
15477 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15478 /*To keep GUI happy*/
15479 return 0;
15480 }
15481
Jeff Johnson295189b2012-06-20 16:38:30 -070015482 for (i = 0; i < ERLeng; i++)
15483 {
Jeff Johnsone7245742012-09-05 17:12:55 -070015484 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070015485 {
15486 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
15487 {
15488 currentRate = supported_data_rate[j].supported_rate[rssidx];
15489 break;
15490 }
15491 }
15492 /* Update MAX rate */
15493 maxRate = (currentRate > maxRate)?currentRate:maxRate;
15494 }
c_hpothu79aab322014-07-14 21:11:01 +053015495
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015496 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053015497 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053015498 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053015499 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070015500 {
c_hpothu79aab322014-07-14 21:11:01 +053015501 if (rate_flags & eHAL_TX_RATE_VHT80)
15502 mode = 2;
15503 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
15504 mode = 1;
15505 else
15506 mode = 0;
15507
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053015508 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
15509 MCSRates, &MCSLeng))
15510 {
15511 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
15512 /*To keep GUI happy*/
15513 return 0;
15514 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015515 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070015516#ifdef WLAN_FEATURE_11AC
15517 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015518 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070015519 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015520 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015521 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070015522 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070015523 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015524 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015525 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015526 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070015527 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015528 maxMCSIdx = 7;
15529 }
15530 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
15531 {
15532 maxMCSIdx = 8;
15533 }
15534 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
15535 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015536 //VHT20 is supporting 0~8
15537 if (rate_flags & eHAL_TX_RATE_VHT20)
15538 maxMCSIdx = 8;
15539 else
15540 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070015541 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015542
c_hpothu79aab322014-07-14 21:11:01 +053015543 if (0 != rssidx)/*check for scaled */
15544 {
15545 //get middle rate MCS index if rssi=1/2
15546 for (i=0; i <= maxMCSIdx; i++)
15547 {
15548 if (sinfo->signal <= rssiMcsTbl[mode][i])
15549 {
15550 maxMCSIdx = i;
15551 break;
15552 }
15553 }
15554 }
15555
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015556 if (rate_flags & eHAL_TX_RATE_VHT80)
15557 {
15558 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
15559 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
15560 }
15561 else if (rate_flags & eHAL_TX_RATE_VHT40)
15562 {
15563 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
15564 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
15565 }
15566 else if (rate_flags & eHAL_TX_RATE_VHT20)
15567 {
15568 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
15569 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
15570 }
15571
Leo Chang6f8870f2013-03-26 18:11:36 -070015572 maxSpeedMCS = 1;
15573 if (currentRate > maxRate)
15574 {
15575 maxRate = currentRate;
15576 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015577
Leo Chang6f8870f2013-03-26 18:11:36 -070015578 }
15579 else
15580#endif /* WLAN_FEATURE_11AC */
15581 {
15582 if (rate_flags & eHAL_TX_RATE_HT40)
15583 {
15584 rateFlag |= 1;
15585 }
15586 if (rate_flags & eHAL_TX_RATE_SGI)
15587 {
15588 rateFlag |= 2;
15589 }
15590
Girish Gowli01abcee2014-07-31 20:18:55 +053015591 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053015592 if (rssidx == 1 || rssidx == 2)
15593 {
15594 //get middle rate MCS index if rssi=1/2
15595 for (i=0; i <= 7; i++)
15596 {
15597 if (sinfo->signal <= rssiMcsTbl[mode][i])
15598 {
15599 temp = i+1;
15600 break;
15601 }
15602 }
15603 }
c_hpothu79aab322014-07-14 21:11:01 +053015604
15605 for (i = 0; i < MCSLeng; i++)
15606 {
Leo Chang6f8870f2013-03-26 18:11:36 -070015607 for (j = 0; j < temp; j++)
15608 {
15609 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
15610 {
15611 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053015612 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070015613 break;
15614 }
15615 }
15616 if ((j < temp) && (currentRate > maxRate))
15617 {
15618 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070015619 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015620 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053015621 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070015622 }
15623 }
15624
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015625 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
15626 {
15627 maxRate = myRate;
15628 maxSpeedMCS = 1;
15629 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
15630 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015631 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053015632 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070015633 {
15634 maxRate = myRate;
15635 if (rate_flags & eHAL_TX_RATE_LEGACY)
15636 {
15637 maxSpeedMCS = 0;
15638 }
15639 else
15640 {
15641 maxSpeedMCS = 1;
15642 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
15643 }
15644 }
15645
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015646 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070015647 {
15648 sinfo->txrate.legacy = maxRate;
15649#ifdef LINKSPEED_DEBUG_ENABLED
15650 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
15651#endif //LINKSPEED_DEBUG_ENABLED
15652 }
15653 else
15654 {
15655 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070015656#ifdef WLAN_FEATURE_11AC
15657 sinfo->txrate.nss = 1;
15658 if (rate_flags & eHAL_TX_RATE_VHT80)
15659 {
15660 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015661 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070015662 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015663 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070015664 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015665 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15666 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15667 }
15668 else if (rate_flags & eHAL_TX_RATE_VHT20)
15669 {
15670 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15671 }
15672#endif /* WLAN_FEATURE_11AC */
15673 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
15674 {
15675 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
15676 if (rate_flags & eHAL_TX_RATE_HT40)
15677 {
15678 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15679 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015680 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015681 if (rate_flags & eHAL_TX_RATE_SGI)
15682 {
15683 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
15684 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053015685
Jeff Johnson295189b2012-06-20 16:38:30 -070015686#ifdef LINKSPEED_DEBUG_ENABLED
15687 pr_info("Reporting MCS rate %d flags %x\n",
15688 sinfo->txrate.mcs,
15689 sinfo->txrate.flags );
15690#endif //LINKSPEED_DEBUG_ENABLED
15691 }
15692 }
15693 else
15694 {
15695 // report current rate instead of max rate
15696
15697 if (rate_flags & eHAL_TX_RATE_LEGACY)
15698 {
15699 //provide to the UI in units of 100kbps
15700 sinfo->txrate.legacy = myRate;
15701#ifdef LINKSPEED_DEBUG_ENABLED
15702 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
15703#endif //LINKSPEED_DEBUG_ENABLED
15704 }
15705 else
15706 {
15707 //must be MCS
15708 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070015709#ifdef WLAN_FEATURE_11AC
15710 sinfo->txrate.nss = 1;
15711 if (rate_flags & eHAL_TX_RATE_VHT80)
15712 {
15713 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
15714 }
15715 else
15716#endif /* WLAN_FEATURE_11AC */
15717 {
15718 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
15719 }
Jeff Johnson295189b2012-06-20 16:38:30 -070015720 if (rate_flags & eHAL_TX_RATE_SGI)
15721 {
15722 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
15723 }
15724 if (rate_flags & eHAL_TX_RATE_HT40)
15725 {
15726 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
15727 }
Leo Chang6f8870f2013-03-26 18:11:36 -070015728#ifdef WLAN_FEATURE_11AC
15729 else if (rate_flags & eHAL_TX_RATE_VHT80)
15730 {
15731 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
15732 }
15733#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070015734#ifdef LINKSPEED_DEBUG_ENABLED
15735 pr_info("Reporting actual MCS rate %d flags %x\n",
15736 sinfo->txrate.mcs,
15737 sinfo->txrate.flags );
15738#endif //LINKSPEED_DEBUG_ENABLED
15739 }
15740 }
15741 sinfo->filled |= STATION_INFO_TX_BITRATE;
15742
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070015743 sinfo->tx_packets =
15744 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
15745 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
15746 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
15747 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
15748
15749 sinfo->tx_retries =
15750 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
15751 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
15752 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
15753 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
15754
15755 sinfo->tx_failed =
15756 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
15757 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
15758 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
15759 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
15760
15761 sinfo->filled |=
15762 STATION_INFO_TX_PACKETS |
15763 STATION_INFO_TX_RETRIES |
15764 STATION_INFO_TX_FAILED;
15765
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015766 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15767 TRACE_CODE_HDD_CFG80211_GET_STA,
15768 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070015769 EXIT();
15770 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070015771}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015772#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15773static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
15774 const u8* mac, struct station_info *sinfo)
15775#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015776static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
15777 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015778#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015779{
15780 int ret;
15781
15782 vos_ssr_protect(__func__);
15783 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
15784 vos_ssr_unprotect(__func__);
15785
15786 return ret;
15787}
15788
15789static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070015790 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070015791{
15792 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015793 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070015794 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015795 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015796
Jeff Johnsone7245742012-09-05 17:12:55 -070015797 ENTER();
15798
Jeff Johnson295189b2012-06-20 16:38:30 -070015799 if (NULL == pAdapter)
15800 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015801 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015802 return -ENODEV;
15803 }
15804
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015805 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15806 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
15807 pAdapter->sessionId, timeout));
15808
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015809 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015810 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015811 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015812 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015813 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015814 }
15815
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015816 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
15817 (TRUE == pHddCtx->hdd_wlan_suspended) &&
15818 (pHddCtx->cfg_ini->fhostArpOffload) &&
15819 (eConnectionState_Associated ==
15820 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
15821 {
Amar Singhald53568e2013-09-26 11:03:45 -070015822
15823 hddLog(VOS_TRACE_LEVEL_INFO,
15824 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053015825 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015826 if (!VOS_IS_STATUS_SUCCESS(vos_status))
15827 {
15828 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015829 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053015830 __func__, vos_status);
15831 }
15832 }
15833
Jeff Johnson295189b2012-06-20 16:38:30 -070015834 /**The get power cmd from the supplicant gets updated by the nl only
15835 *on successful execution of the function call
15836 *we are oppositely mapped w.r.t mode in the driver
15837 **/
15838 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
15839
15840 if (VOS_STATUS_E_FAILURE == vos_status)
15841 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015842 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15843 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015844 return -EINVAL;
15845 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015846 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070015847 return 0;
15848}
15849
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015850static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
15851 struct net_device *dev, bool mode, int timeout)
15852{
15853 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070015854
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015855 vos_ssr_protect(__func__);
15856 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
15857 vos_ssr_unprotect(__func__);
15858
15859 return ret;
15860}
Sushant Kaushik084f6592015-09-10 13:11:56 +053015861
Jeff Johnson295189b2012-06-20 16:38:30 -070015862#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015863static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
15864 struct net_device *netdev,
15865 u8 key_index)
15866{
15867 ENTER();
15868 return 0;
15869}
15870
Jeff Johnson295189b2012-06-20 16:38:30 -070015871static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015872 struct net_device *netdev,
15873 u8 key_index)
15874{
15875 int ret;
15876 vos_ssr_protect(__func__);
15877 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
15878 vos_ssr_unprotect(__func__);
15879 return ret;
15880}
15881#endif //LINUX_VERSION_CODE
15882
15883#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
15884static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
15885 struct net_device *dev,
15886 struct ieee80211_txq_params *params)
15887{
15888 ENTER();
15889 return 0;
15890}
15891#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
15892static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
15893 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070015894{
Jeff Johnsone7245742012-09-05 17:12:55 -070015895 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070015896 return 0;
15897}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015898#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070015899
15900#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
15901static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015902 struct net_device *dev,
15903 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070015904{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015905 int ret;
15906
15907 vos_ssr_protect(__func__);
15908 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
15909 vos_ssr_unprotect(__func__);
15910 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070015911}
15912#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
15913static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
15914 struct ieee80211_txq_params *params)
15915{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015916 int ret;
15917
15918 vos_ssr_protect(__func__);
15919 ret = __wlan_hdd_set_txq_params(wiphy, params);
15920 vos_ssr_unprotect(__func__);
15921 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070015922}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015923#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070015924
Naresh Jayaram69e3f282014-10-14 12:29:12 +053015925static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015926 struct net_device *dev,
15927 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070015928{
15929 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015930 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015931 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015932 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015933 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015934 v_CONTEXT_t pVosContext = NULL;
15935 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015936
Jeff Johnsone7245742012-09-05 17:12:55 -070015937 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015938
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015939 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070015940 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015941 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070015942 return -EINVAL;
15943 }
15944
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015945 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15946 TRACE_CODE_HDD_CFG80211_DEL_STA,
15947 pAdapter->sessionId, pAdapter->device_mode));
15948
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015949 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15950 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015951 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015952 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015953 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015954 }
15955
Jeff Johnson295189b2012-06-20 16:38:30 -070015956 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070015957 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070015958 )
15959 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015960 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
15961 pSapCtx = VOS_GET_SAP_CB(pVosContext);
15962 if(pSapCtx == NULL){
15963 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15964 FL("psapCtx is NULL"));
15965 return -ENOENT;
15966 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015967 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070015968 {
15969 v_U16_t i;
15970 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
15971 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015972 if ((pSapCtx->aStaInfo[i].isUsed) &&
15973 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070015974 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015975 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015976 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015977 ETHER_ADDR_LEN);
15978
Jeff Johnson295189b2012-06-20 16:38:30 -070015979 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080015980 "%s: Delete STA with MAC::"
15981 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015982 __func__,
15983 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
15984 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070015985 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053015986 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070015987 }
15988 }
15989 }
15990 else
15991 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015992
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053015993 vos_status = hdd_softap_GetStaId(pAdapter,
15994 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080015995 if (!VOS_IS_STATUS_SUCCESS(vos_status))
15996 {
15997 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080015998 "%s: Skip this DEL STA as this is not used::"
15999 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016000 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016001 return -ENOENT;
16002 }
16003
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016004 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016005 {
16006 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080016007 "%s: Skip this DEL STA as deauth is in progress::"
16008 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016009 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016010 return -ENOENT;
16011 }
16012
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016013 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016014
Jeff Johnson295189b2012-06-20 16:38:30 -070016015 hddLog(VOS_TRACE_LEVEL_INFO,
16016 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016017 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070016018 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016019 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016020
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016021 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016022 if (!VOS_IS_STATUS_SUCCESS(vos_status))
16023 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053016024 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016025 hddLog(VOS_TRACE_LEVEL_INFO,
16026 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080016027 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016028 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016029 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080016030 return -ENOENT;
16031 }
16032
Jeff Johnson295189b2012-06-20 16:38:30 -070016033 }
16034 }
16035
16036 EXIT();
16037
16038 return 0;
16039}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016040
16041#ifdef CFG80211_DEL_STA_V2
16042static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16043 struct net_device *dev,
16044 struct station_del_parameters *param)
16045#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016046#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16047static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16048 struct net_device *dev, const u8 *mac)
16049#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016050static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
16051 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016052#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016053#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016054{
16055 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016056 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070016057
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016058 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016059
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016060#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016061 if (NULL == param) {
16062 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016063 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016064 return -EINVAL;
16065 }
16066
16067 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
16068 param->subtype, &delStaParams);
16069
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016070#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053016071 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016072 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053016073#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053016074 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
16075
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016076 vos_ssr_unprotect(__func__);
16077
16078 return ret;
16079}
16080
16081static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016082 struct net_device *dev,
16083#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16084 const u8 *mac,
16085#else
16086 u8 *mac,
16087#endif
16088 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016089{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016090 hdd_adapter_t *pAdapter;
16091 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016092 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016093#ifdef FEATURE_WLAN_TDLS
16094 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016095
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016096 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016097
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016098 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16099 if (NULL == pAdapter)
16100 {
16101 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16102 "%s: Adapter is NULL",__func__);
16103 return -EINVAL;
16104 }
16105 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16106 status = wlan_hdd_validate_context(pHddCtx);
16107 if (0 != status)
16108 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016109 return status;
16110 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016111
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016112 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16113 TRACE_CODE_HDD_CFG80211_ADD_STA,
16114 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016115 mask = params->sta_flags_mask;
16116
16117 set = params->sta_flags_set;
16118
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016119 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016120 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
16121 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016122
16123 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
16124 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080016125 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016126 }
16127 }
16128#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016129 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016130 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070016131}
16132
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016133#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16134static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16135 struct net_device *dev, const u8 *mac,
16136 struct station_parameters *params)
16137#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016138static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
16139 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053016140#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016141{
16142 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016143
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016144 vos_ssr_protect(__func__);
16145 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
16146 vos_ssr_unprotect(__func__);
16147
16148 return ret;
16149}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016150#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070016151
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016152static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070016153 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016154{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016155 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16156 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016157 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016158 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016159 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016160 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070016161
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016162 ENTER();
16163
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016164 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016165 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016166 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016167 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016168 return -EINVAL;
16169 }
16170
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016171 if (!pmksa) {
16172 hddLog(LOGE, FL("pmksa is NULL"));
16173 return -EINVAL;
16174 }
16175
16176 if (!pmksa->bssid || !pmksa->pmkid) {
16177 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
16178 pmksa->bssid, pmksa->pmkid);
16179 return -EINVAL;
16180 }
16181
16182 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
16183 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16184
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016185 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16186 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016187 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016188 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016189 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016190 }
16191
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016192 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016193 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16194
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016195 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
16196 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016197
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016198 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016199 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016200 &pmk_id, 1, FALSE);
16201
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016202 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16203 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
16204 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016205
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016206 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016207 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016208}
16209
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016210static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
16211 struct cfg80211_pmksa *pmksa)
16212{
16213 int ret;
16214
16215 vos_ssr_protect(__func__);
16216 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
16217 vos_ssr_unprotect(__func__);
16218
16219 return ret;
16220}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016221
Wilson Yang6507c4e2013-10-01 20:11:19 -070016222
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016223static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070016224 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016225{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016226 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16227 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016228 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016229 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016230
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016231 ENTER();
16232
Wilson Yang6507c4e2013-10-01 20:11:19 -070016233 /* Validate pAdapter */
16234 if (NULL == pAdapter)
16235 {
16236 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
16237 return -EINVAL;
16238 }
16239
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016240 if (!pmksa) {
16241 hddLog(LOGE, FL("pmksa is NULL"));
16242 return -EINVAL;
16243 }
16244
16245 if (!pmksa->bssid) {
16246 hddLog(LOGE, FL("pmksa->bssid is NULL"));
16247 return -EINVAL;
16248 }
16249
Kiet Lam98c46a12014-10-31 15:34:57 -070016250 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
16251 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
16252
Wilson Yang6507c4e2013-10-01 20:11:19 -070016253 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16254 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016255 if (0 != status)
16256 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016257 return status;
16258 }
16259
16260 /*Retrieve halHandle*/
16261 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16262
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016263 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16264 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
16265 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016266 /* Delete the PMKID CSR cache */
16267 if (eHAL_STATUS_SUCCESS !=
16268 sme_RoamDelPMKIDfromCache(halHandle,
16269 pAdapter->sessionId, pmksa->bssid, FALSE)) {
16270 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
16271 MAC_ADDR_ARRAY(pmksa->bssid));
16272 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016273 }
16274
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016275 EXIT();
16276 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016277}
16278
Wilson Yang6507c4e2013-10-01 20:11:19 -070016279
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016280static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
16281 struct cfg80211_pmksa *pmksa)
16282{
16283 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016284
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016285 vos_ssr_protect(__func__);
16286 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
16287 vos_ssr_unprotect(__func__);
16288
16289 return ret;
16290
16291}
16292
16293static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016294{
Wilson Yang6507c4e2013-10-01 20:11:19 -070016295 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16296 tHalHandle halHandle;
16297 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080016298 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016299
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016300 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070016301
16302 /* Validate pAdapter */
16303 if (NULL == pAdapter)
16304 {
16305 hddLog(VOS_TRACE_LEVEL_ERROR,
16306 "%s: Invalid Adapter" ,__func__);
16307 return -EINVAL;
16308 }
16309
16310 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16311 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070016312 if (0 != status)
16313 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070016314 return status;
16315 }
16316
16317 /*Retrieve halHandle*/
16318 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16319
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053016320 /* Flush the PMKID cache in CSR */
16321 if (eHAL_STATUS_SUCCESS !=
16322 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
16323 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
16324 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070016325 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016326 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080016327 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016328}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053016329
16330static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
16331{
16332 int ret;
16333
16334 vos_ssr_protect(__func__);
16335 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
16336 vos_ssr_unprotect(__func__);
16337
16338 return ret;
16339}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016340#endif
16341
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016342#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016343static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16344 struct net_device *dev,
16345 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016346{
16347 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16348 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016349 hdd_context_t *pHddCtx;
16350 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016351
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016352 ENTER();
16353
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016354 if (NULL == pAdapter)
16355 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016356 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016357 return -ENODEV;
16358 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016359 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16360 ret = wlan_hdd_validate_context(pHddCtx);
16361 if (0 != ret)
16362 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016363 return ret;
16364 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016365 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016366 if (NULL == pHddStaCtx)
16367 {
16368 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
16369 return -EINVAL;
16370 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016371
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016372 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16373 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
16374 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016375 // Added for debug on reception of Re-assoc Req.
16376 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
16377 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080016378 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016379 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080016380 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016381 }
16382
16383#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080016384 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016385 ftie->ie_len);
16386#endif
16387
16388 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053016389 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
16390 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016391 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016392
16393 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016394 return 0;
16395}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016396
16397static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
16398 struct net_device *dev,
16399 struct cfg80211_update_ft_ies_params *ftie)
16400{
16401 int ret;
16402
16403 vos_ssr_protect(__func__);
16404 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
16405 vos_ssr_unprotect(__func__);
16406
16407 return ret;
16408}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016409#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016410
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016411#ifdef FEATURE_WLAN_SCAN_PNO
16412
16413void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
16414 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
16415{
16416 int ret;
16417 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
16418 hdd_context_t *pHddCtx;
16419
Nirav Shah80830bf2013-12-31 16:35:12 +053016420 ENTER();
16421
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016422 if (NULL == pAdapter)
16423 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016424 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016425 "%s: HDD adapter is Null", __func__);
16426 return ;
16427 }
16428
16429 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16430 if (NULL == pHddCtx)
16431 {
16432 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16433 "%s: HDD context is Null!!!", __func__);
16434 return ;
16435 }
16436
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016437 spin_lock(&pHddCtx->schedScan_lock);
16438 if (TRUE == pHddCtx->isWiphySuspended)
16439 {
16440 pHddCtx->isSchedScanUpdatePending = TRUE;
16441 spin_unlock(&pHddCtx->schedScan_lock);
16442 hddLog(VOS_TRACE_LEVEL_INFO,
16443 "%s: Update cfg80211 scan database after it resume", __func__);
16444 return ;
16445 }
16446 spin_unlock(&pHddCtx->schedScan_lock);
16447
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016448 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
16449
16450 if (0 > ret)
16451 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Mahesh A Saptasagarfb49cdd2015-10-16 18:41:59 +053016452 else
16453 {
16454 /* Acquire wakelock to handle the case where APP's tries to suspend
16455 * immediatly after the driver gets connect request(i.e after pno)
16456 * from supplicant, this result in app's is suspending and not able
16457 * to process the connect request to AP */
16458 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
16459 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016460 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016461 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16462 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016463}
16464
16465/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016466 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016467 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016468 */
16469static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
16470{
16471 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
16472 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016473 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016474 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16475 int status = 0;
16476 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
16477
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016478 /* The current firmware design does not allow PNO during any
16479 * active sessions. Hence, determine the active sessions
16480 * and return a failure.
16481 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016482 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
16483 {
16484 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016485 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016486
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016487 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
16488 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
16489 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
16490 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
16491 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053016492 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016493 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016494 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016495 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016496 }
16497 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16498 pAdapterNode = pNext;
16499 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016500 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016501}
16502
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016503void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
16504{
16505 hdd_adapter_t *pAdapter = callbackContext;
16506 hdd_context_t *pHddCtx;
16507
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016508 ENTER();
16509
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016510 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
16511 {
16512 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16513 FL("Invalid adapter or adapter has invalid magic"));
16514 return;
16515 }
16516
16517 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16518 if (0 != wlan_hdd_validate_context(pHddCtx))
16519 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016520 return;
16521 }
16522
c_hpothub53c45d2014-08-18 16:53:14 +053016523 if (VOS_STATUS_SUCCESS != status)
16524 {
16525 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016526 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053016527 pHddCtx->isPnoEnable = FALSE;
16528 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016529
16530 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
16531 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016532 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016533}
16534
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016535/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016536 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
16537 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016538 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016539static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016540 struct net_device *dev, struct cfg80211_sched_scan_request *request)
16541{
16542 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016543 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016544 hdd_context_t *pHddCtx;
16545 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016546 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053016547 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
16548 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016549 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
16550 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016551 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016552 hdd_config_t *pConfig = NULL;
16553 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016554
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016555 ENTER();
16556
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016557 if (NULL == pAdapter)
16558 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016560 "%s: HDD adapter is Null", __func__);
16561 return -ENODEV;
16562 }
16563
16564 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016565 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016566
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016567 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016568 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016569 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016570 }
16571
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016572 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016573 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16574 if (NULL == hHal)
16575 {
16576 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16577 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016578 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016579 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016580 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16581 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
16582 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053016583 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016584 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053016585 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053016586 {
16587 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16588 "%s: aborting the existing scan is unsuccessfull", __func__);
16589 return -EBUSY;
16590 }
16591
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016592 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016593 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053016594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053016595 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053016596 return -EBUSY;
16597 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016598
c_hpothu37f21312014-04-09 21:49:54 +053016599 if (TRUE == pHddCtx->isPnoEnable)
16600 {
16601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
16602 FL("already PNO is enabled"));
16603 return -EBUSY;
16604 }
c_hpothu225aa7c2014-10-22 17:45:13 +053016605
16606 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
16607 {
16608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16609 "%s: abort ROC failed ", __func__);
16610 return -EBUSY;
16611 }
16612
c_hpothu37f21312014-04-09 21:49:54 +053016613 pHddCtx->isPnoEnable = TRUE;
16614
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016615 pnoRequest.enable = 1; /*Enable PNO */
16616 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016617
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016618 if (( !pnoRequest.ucNetworksCount ) ||
16619 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016620 {
16621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016622 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016623 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016624 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016625 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016626 goto error;
16627 }
16628
16629 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
16630 {
16631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016632 "%s: Incorrect number of channels %d",
16633 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016634 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016635 goto error;
16636 }
16637
16638 /* Framework provides one set of channels(all)
16639 * common for all saved profile */
16640 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
16641 channels_allowed, &num_channels_allowed))
16642 {
16643 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16644 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016645 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016646 goto error;
16647 }
16648 /* Checking each channel against allowed channel list */
16649 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053016650 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016651 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016652 char chList [(request->n_channels*5)+1];
16653 int len;
16654 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016655 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016656 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016657 {
Nirav Shah80830bf2013-12-31 16:35:12 +053016658 if (request->channels[i]->hw_value == channels_allowed[indx])
16659 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016660 if ((!pConfig->enableDFSPnoChnlScan) &&
16661 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
16662 {
16663 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16664 "%s : Dropping DFS channel : %d",
16665 __func__,channels_allowed[indx]);
16666 num_ignore_dfs_ch++;
16667 break;
16668 }
16669
Nirav Shah80830bf2013-12-31 16:35:12 +053016670 valid_ch[num_ch++] = request->channels[i]->hw_value;
16671 len += snprintf(chList+len, 5, "%d ",
16672 request->channels[i]->hw_value);
16673 break ;
16674 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016675 }
16676 }
Nirav Shah80830bf2013-12-31 16:35:12 +053016677 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016678
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053016679 /*If all channels are DFS and dropped, then ignore the PNO request*/
16680 if (num_ignore_dfs_ch == request->n_channels)
16681 {
16682 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16683 "%s : All requested channels are DFS channels", __func__);
16684 ret = -EINVAL;
16685 goto error;
16686 }
16687 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016688
16689 pnoRequest.aNetworks =
16690 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16691 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016692 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016693 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16694 FL("failed to allocate memory aNetworks %u"),
16695 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16696 goto error;
16697 }
16698 vos_mem_zero(pnoRequest.aNetworks,
16699 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
16700
16701 /* Filling per profile params */
16702 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
16703 {
16704 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016705 request->match_sets[i].ssid.ssid_len;
16706
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016707 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
16708 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016709 {
16710 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016711 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016712 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016713 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016714 goto error;
16715 }
16716
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016717 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016718 request->match_sets[i].ssid.ssid,
16719 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053016720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16721 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016722 i, pnoRequest.aNetworks[i].ssId.ssId);
16723 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
16724 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
16725 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016726
16727 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016728 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
16729 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016730
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016731 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016732 }
16733
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016734 for (i = 0; i < request->n_ssids; i++)
16735 {
16736 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016737 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016738 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016739 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016740 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016741 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016742 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016743 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016744 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016745 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053016746 break;
16747 }
16748 j++;
16749 }
16750 }
16751 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16752 "Number of hidden networks being Configured = %d",
16753 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016754 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080016755 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016756
16757 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
16758 if (pnoRequest.p24GProbeTemplate == NULL)
16759 {
16760 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16761 FL("failed to allocate memory p24GProbeTemplate %u"),
16762 SIR_PNO_MAX_PB_REQ_SIZE);
16763 goto error;
16764 }
16765
16766 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
16767 if (pnoRequest.p5GProbeTemplate == NULL)
16768 {
16769 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
16770 FL("failed to allocate memory p5GProbeTemplate %u"),
16771 SIR_PNO_MAX_PB_REQ_SIZE);
16772 goto error;
16773 }
16774
16775 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
16776 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
16777
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053016778 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
16779 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016780 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016781 pnoRequest.us24GProbeTemplateLen = request->ie_len;
16782 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
16783 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016784
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016785 pnoRequest.us5GProbeTemplateLen = request->ie_len;
16786 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
16787 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053016788 }
16789
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016790 /* Driver gets only one time interval which is hardcoded in
16791 * supplicant for 10000ms. Taking power consumption into account 6 timers
16792 * will be used, Timervalue is increased exponentially i.e 10,20,40,
16793 * 80,160,320 secs. And number of scan cycle for each timer
16794 * is configurable through INI param gPNOScanTimerRepeatValue.
16795 * If it is set to 0 only one timer will be used and PNO scan cycle
16796 * will be repeated after each interval specified by supplicant
16797 * till PNO is disabled.
16798 */
16799 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016800 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016801 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016802 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016803 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
16804
16805 tempInterval = (request->interval)/1000;
16806 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16807 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
16808 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016809 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016810 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016811 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016812 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016813 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016814 tempInterval *= 2;
16815 }
16816 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016817 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053016818
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016819 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016820
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016821 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016822 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
16823 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016824 pAdapter->pno_req_status = 0;
16825
Nirav Shah80830bf2013-12-31 16:35:12 +053016826 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16827 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016828 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
16829 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053016830
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016831 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016832 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016833 hdd_cfg80211_sched_scan_done_callback, pAdapter);
16834 if (eHAL_STATUS_SUCCESS != status)
16835 {
16836 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053016837 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016838 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016839 goto error;
16840 }
16841
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016842 ret = wait_for_completion_timeout(
16843 &pAdapter->pno_comp_var,
16844 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
16845 if (0 >= ret)
16846 {
16847 // Did not receive the response for PNO enable in time.
16848 // Assuming the PNO enable was success.
16849 // Returning error from here, because we timeout, results
16850 // in side effect of Wifi (Wifi Setting) not to work.
16851 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16852 FL("Timed out waiting for PNO to be Enabled"));
16853 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016854 }
16855
16856 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053016857 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016858
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016859error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016860 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16861 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053016862 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016863 if (pnoRequest.aNetworks)
16864 vos_mem_free(pnoRequest.aNetworks);
16865 if (pnoRequest.p24GProbeTemplate)
16866 vos_mem_free(pnoRequest.p24GProbeTemplate);
16867 if (pnoRequest.p5GProbeTemplate)
16868 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016869
16870 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016871 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016872}
16873
16874/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016875 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
16876 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016877 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016878static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
16879 struct net_device *dev, struct cfg80211_sched_scan_request *request)
16880{
16881 int ret;
16882
16883 vos_ssr_protect(__func__);
16884 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
16885 vos_ssr_unprotect(__func__);
16886
16887 return ret;
16888}
16889
16890/*
16891 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
16892 * Function to disable PNO
16893 */
16894static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016895 struct net_device *dev)
16896{
16897 eHalStatus status = eHAL_STATUS_FAILURE;
16898 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16899 hdd_context_t *pHddCtx;
16900 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016901 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016902 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016903
16904 ENTER();
16905
16906 if (NULL == pAdapter)
16907 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016908 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016909 "%s: HDD adapter is Null", __func__);
16910 return -ENODEV;
16911 }
16912
16913 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016914
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016915 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016916 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016917 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016918 "%s: HDD context is Null", __func__);
16919 return -ENODEV;
16920 }
16921
16922 /* The return 0 is intentional when isLogpInProgress and
16923 * isLoadUnloadInProgress. We did observe a crash due to a return of
16924 * failure in sched_scan_stop , especially for a case where the unload
16925 * of the happens at the same time. The function __cfg80211_stop_sched_scan
16926 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
16927 * success. If it returns a failure , then its next invocation due to the
16928 * clean up of the second interface will have the dev pointer corresponding
16929 * to the first one leading to a crash.
16930 */
16931 if (pHddCtx->isLogpInProgress)
16932 {
16933 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16934 "%s: LOGP in Progress. Ignore!!!", __func__);
Mahesh A Saptasagar0c11d822015-10-08 19:54:08 +053016935 pHddCtx->isPnoEnable = FALSE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016936 return ret;
16937 }
16938
Mihir Shete18156292014-03-11 15:38:30 +053016939 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016940 {
16941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16942 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
16943 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016944 }
16945
16946 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16947 if (NULL == hHal)
16948 {
16949 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16950 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016951 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016952 }
16953
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016954 pnoRequest.enable = 0; /* Disable PNO */
16955 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016956
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016957 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16958 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
16959 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053016960 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016961 pAdapter->sessionId,
16962 NULL, pAdapter);
16963 if (eHAL_STATUS_SUCCESS != status)
16964 {
16965 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16966 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016967 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016968 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016969 }
c_hpothu37f21312014-04-09 21:49:54 +053016970 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016971
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016972error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016973 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053016974 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016975
16976 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053016977 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016978}
16979
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053016980/*
16981 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
16982 * NL interface to disable PNO
16983 */
16984static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
16985 struct net_device *dev)
16986{
16987 int ret;
16988
16989 vos_ssr_protect(__func__);
16990 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
16991 vos_ssr_unprotect(__func__);
16992
16993 return ret;
16994}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016995#endif /*FEATURE_WLAN_SCAN_PNO*/
16996
16997
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016998#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016999#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017000static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17001 struct net_device *dev,
17002 u8 *peer, u8 action_code,
17003 u8 dialog_token,
17004 u16 status_code, u32 peer_capability,
17005 const u8 *buf, size_t len)
17006#else /* TDLS_MGMT_VERSION2 */
17007#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17008static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17009 struct net_device *dev,
17010 const u8 *peer, u8 action_code,
17011 u8 dialog_token, u16 status_code,
17012 u32 peer_capability, bool initiator,
17013 const u8 *buf, size_t len)
17014#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17015static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17016 struct net_device *dev,
17017 const u8 *peer, u8 action_code,
17018 u8 dialog_token, u16 status_code,
17019 u32 peer_capability, const u8 *buf,
17020 size_t len)
17021#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17022static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17023 struct net_device *dev,
17024 u8 *peer, u8 action_code,
17025 u8 dialog_token,
17026 u16 status_code, u32 peer_capability,
17027 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017028#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017029static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17030 struct net_device *dev,
17031 u8 *peer, u8 action_code,
17032 u8 dialog_token,
17033 u16 status_code, const u8 *buf,
17034 size_t len)
17035#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017036#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017037{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017038 hdd_adapter_t *pAdapter;
17039 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017040 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070017041 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080017042 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070017043 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017044 int ret;
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017045 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017046#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053017047 u32 peer_capability = 0;
17048#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017049 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017050 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017051
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017052 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17053 if (NULL == pAdapter)
17054 {
17055 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17056 "%s: Adapter is NULL",__func__);
17057 return -EINVAL;
17058 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017059 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17060 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
17061 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017062
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017063 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017064 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017065 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017066 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017067 "Invalid arguments");
17068 return -EINVAL;
17069 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017070
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017071 if (pHddCtx->isLogpInProgress)
17072 {
17073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17074 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053017075 wlan_hdd_tdls_set_link_status(pAdapter,
17076 peer,
17077 eTDLS_LINK_IDLE,
17078 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017079 return -EBUSY;
17080 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017081
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017082 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
17083 {
17084 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17085 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
17086 return -EAGAIN;
17087 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017088
Hoonki Lee27511902013-03-14 18:19:06 -070017089 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017090 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017091 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017092 "%s: TDLS mode is disabled OR not enabled in FW."
17093 MAC_ADDRESS_STR " action %d declined.",
17094 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017095 return -ENOTSUPP;
17096 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017097
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017098 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17099
17100 if( NULL == pHddStaCtx )
17101 {
17102 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17103 "%s: HDD station context NULL ",__func__);
17104 return -EINVAL;
17105 }
17106
17107 /* STA should be connected and authenticated
17108 * before sending any TDLS frames
17109 */
17110 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
17111 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
17112 {
17113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17114 "STA is not connected or unauthenticated. "
17115 "connState %u, uIsAuthenticated %u",
17116 pHddStaCtx->conn_info.connState,
17117 pHddStaCtx->conn_info.uIsAuthenticated);
17118 return -EAGAIN;
17119 }
17120
Hoonki Lee27511902013-03-14 18:19:06 -070017121 /* other than teardown frame, other mgmt frames are not sent if disabled */
17122 if (SIR_MAC_TDLS_TEARDOWN != action_code)
17123 {
17124 /* if tdls_mode is disabled to respond to peer's request */
17125 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
17126 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017127 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070017128 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017129 " TDLS mode is disabled. action %d declined.",
17130 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070017131
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017132 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070017133 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053017134
17135 if (vos_max_concurrent_connections_reached())
17136 {
17137 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
17138 return -EINVAL;
17139 }
Hoonki Lee27511902013-03-14 18:19:06 -070017140 }
17141
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017142 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
17143 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053017144 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017145 {
17146 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017147 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017148 " TDLS setup is ongoing. action %d declined.",
17149 __func__, MAC_ADDR_ARRAY(peer), action_code);
17150 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017151 }
17152 }
17153
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017154 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
17155 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080017156 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017157 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17158 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017159 {
17160 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
17161 we return error code at 'add_station()'. Hence we have this
17162 check again in addtion to add_station().
17163 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017164 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080017165 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017166 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17167 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017168 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
17169 __func__, MAC_ADDR_ARRAY(peer), action_code,
17170 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053017171 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080017172 }
17173 else
17174 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017175 /* maximum reached. tweak to send error code to peer and return
17176 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017177 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17179 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053017180 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
17181 __func__, MAC_ADDR_ARRAY(peer), status_code,
17182 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070017183 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017184 /* fall through to send setup resp with failure status
17185 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080017186 }
17187 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017188 else
17189 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017190 mutex_lock(&pHddCtx->tdls_lock);
17191 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017192 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017193 {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017194 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017195 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070017196 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
17197 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017198 return -EPERM;
17199 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017200 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017201 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080017202 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017203
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017204 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017205 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017206 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
17207 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017208
Hoonki Leea34dd892013-02-05 22:56:02 -080017209 /*Except teardown responder will not be used so just make 0*/
17210 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080017211 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080017212 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017213
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017214 mutex_lock(&pHddCtx->tdls_lock);
17215 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017216
17217 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
17218 responder = pTdlsPeer->is_responder;
17219 else
Hoonki Leea34dd892013-02-05 22:56:02 -080017220 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017221 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053017222 "%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 -070017223 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
17224 dialog_token, status_code, len);
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017225 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070017226 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080017227 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017228 mutex_unlock(&pHddCtx->tdls_lock);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017229 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017230
Masti, Narayanraddi3b681932015-10-08 19:22:25 +053017231 /* Discard TDLS setup if peer is removed by user app */
17232 if ((pHddCtx->cfg_ini->fTDLSExternalControl) &&
17233 ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17234 (SIR_MAC_TDLS_SETUP_CNF == action_code) ||
17235 (SIR_MAC_TDLS_DIS_REQ == action_code))) {
17236
17237 mutex_lock(&pHddCtx->tdls_lock);
17238 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
17239 if (pTdlsPeer && (FALSE == pTdlsPeer->isForcedPeer)) {
17240 mutex_unlock(&pHddCtx->tdls_lock);
17241 hddLog(LOGE, FL("TDLS External Control enabled, but peer "
17242 MAC_ADDRESS_STR " is not forced, so reject the action code %d"),
17243 MAC_ADDR_ARRAY(peer), action_code);
17244 return -EINVAL;
17245 }
17246 mutex_unlock(&pHddCtx->tdls_lock);
17247 }
17248
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017249 /* For explicit trigger of DIS_REQ come out of BMPS for
17250 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070017251 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017252 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
17253 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070017254 {
17255 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
17256 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053017257 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053017258 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017259 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
17260 if (status != VOS_STATUS_SUCCESS) {
17261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
17262 }
Hoonki Lee14621352013-04-16 17:51:19 -070017263 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017264 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017265 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017266 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
17267 }
17268 }
Hoonki Lee14621352013-04-16 17:51:19 -070017269 }
17270
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017271 /* make sure doesn't call send_mgmt() while it is pending */
17272 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
17273 {
17274 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080017275 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017276 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017277 ret = -EBUSY;
17278 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017279 }
17280
17281 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017282 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
17283
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017284 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
17285 pAdapter->sessionId, peer, action_code, dialog_token,
17286 status_code, peer_capability, (tANI_U8 *)buf, len,
17287 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017288
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017289 if (VOS_STATUS_SUCCESS != status)
17290 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017291 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17292 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017293 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017294 ret = -EINVAL;
17295 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017296 }
17297
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017298 if ((SIR_MAC_TDLS_DIS_REQ == action_code) ||
17299 (SIR_MAC_TDLS_DIS_RSP == action_code))
17300 {
17301 /* for DIS_REQ/DIS_RSP, supplicant don't consider the return status.
17302 * So we no need to wait for tdls_mgmt_comp for sending ack status.
17303 */
17304 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17305 "%s: tx done for frm %u", __func__, action_code);
17306 return 0;
17307 }
17308
17309 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17310 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
17311 WAIT_TIME_TDLS_MGMT);
17312
Hoonki Leed37cbb32013-04-20 00:31:14 -070017313 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
17314 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
17315
17316 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017317 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070017318 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070017319 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070017320 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017321 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080017322
17323 if (pHddCtx->isLogpInProgress)
17324 {
17325 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17326 "%s: LOGP in Progress. Ignore!!!", __func__);
17327 return -EAGAIN;
17328 }
Abhishek Singh837adf22015-10-01 17:37:37 +053017329 if (rc <= 0)
17330 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
17331 WLAN_LOG_INDICATOR_HOST_DRIVER,
17332 WLAN_LOG_REASON_HDD_TIME_OUT,
17333 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080017334
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017335 ret = -EINVAL;
17336 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017337 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053017338 else
17339 {
17340 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17341 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
17342 __func__, rc, pAdapter->mgmtTxCompletionStatus);
17343 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017344
Gopichand Nakkala05922802013-03-14 12:23:19 -070017345 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070017346 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017347 ret = max_sta_failed;
17348 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070017349 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017350
Hoonki Leea34dd892013-02-05 22:56:02 -080017351 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
17352 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017353 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017354 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17355 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017356 }
17357 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
17358 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017359 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017360 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
17361 }
Hoonki Leea34dd892013-02-05 22:56:02 -080017362 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017363
17364 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053017365
17366tx_failed:
17367 /* add_station will be called before sending TDLS_SETUP_REQ and
17368 * TDLS_SETUP_RSP and as part of add_station driver will enable
17369 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
17370 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
17371 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
17372 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
17373 */
17374
17375 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
17376 (SIR_MAC_TDLS_SETUP_RSP == action_code))
17377 wlan_hdd_tdls_check_bmps(pAdapter);
17378 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017379}
17380
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017381#if TDLS_MGMT_VERSION2
17382static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17383 u8 *peer, u8 action_code, u8 dialog_token,
17384 u16 status_code, u32 peer_capability,
17385 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017386#else /* TDLS_MGMT_VERSION2 */
17387#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
17388static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17389 struct net_device *dev,
17390 const u8 *peer, u8 action_code,
17391 u8 dialog_token, u16 status_code,
17392 u32 peer_capability, bool initiator,
17393 const u8 *buf, size_t len)
17394#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
17395static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17396 struct net_device *dev,
17397 const u8 *peer, u8 action_code,
17398 u8 dialog_token, u16 status_code,
17399 u32 peer_capability, const u8 *buf,
17400 size_t len)
17401#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
17402static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
17403 struct net_device *dev,
17404 u8 *peer, u8 action_code,
17405 u8 dialog_token,
17406 u16 status_code, u32 peer_capability,
17407 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017408#else
17409static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
17410 u8 *peer, u8 action_code, u8 dialog_token,
17411 u16 status_code, const u8 *buf, size_t len)
17412#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017413#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017414{
17415 int ret;
17416
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017417 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017418#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017419 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17420 dialog_token, status_code,
17421 peer_capability, buf, len);
17422#else /* TDLS_MGMT_VERSION2 */
17423#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
17424 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17425 dialog_token, status_code,
17426 peer_capability, initiator,
17427 buf, len);
17428#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
17429 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17430 dialog_token, status_code,
17431 peer_capability, buf, len);
17432#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
17433 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17434 dialog_token, status_code,
17435 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017436#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017437 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
17438 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017439#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017440#endif
17441 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017442
Anand N Sunkad9f80b742015-07-30 20:05:51 +053017443 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017444}
Atul Mittal115287b2014-07-08 13:26:33 +053017445
17446int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017447#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17448 const u8 *peer,
17449#else
Atul Mittal115287b2014-07-08 13:26:33 +053017450 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017451#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017452 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053017453 cfg80211_exttdls_callback callback)
17454{
17455
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017456 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053017457 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017458 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053017459 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17460 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
17461 __func__, MAC_ADDR_ARRAY(peer));
17462
17463 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17464 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17465
17466 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017467 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17468 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17469 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017470 return -ENOTSUPP;
17471 }
17472
17473 /* To cater the requirement of establishing the TDLS link
17474 * irrespective of the data traffic , get an entry of TDLS peer.
17475 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017476 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017477 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
17478 if (pTdlsPeer == NULL) {
17479 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17480 "%s: peer " MAC_ADDRESS_STR " not existing",
17481 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053017482 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017483 return -EINVAL;
17484 }
17485
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017486 /* check FW TDLS Off Channel capability */
17487 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017488 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053017489 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017490 {
17491 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
17492 pTdlsPeer->peerParams.global_operating_class =
17493 tdls_peer_params->global_operating_class;
17494 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
17495 pTdlsPeer->peerParams.min_bandwidth_kbps =
17496 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017497 /* check configured channel is valid, non dfs and
17498 * not current operating channel */
17499 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
17500 tdls_peer_params->channel)) &&
17501 (pHddStaCtx) &&
17502 (tdls_peer_params->channel !=
17503 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017504 {
17505 pTdlsPeer->isOffChannelConfigured = TRUE;
17506 }
17507 else
17508 {
17509 pTdlsPeer->isOffChannelConfigured = FALSE;
17510 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17511 "%s: Configured Tdls Off Channel is not valid", __func__);
17512
17513 }
17514 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017515 "%s: tdls_off_channel %d isOffChannelConfigured %d "
17516 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017517 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053017518 pTdlsPeer->isOffChannelConfigured,
17519 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017520 }
17521 else
17522 {
17523 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053017524 "%s: TDLS off channel FW capability %d, "
17525 "host capab %d or Invalid TDLS Peer Params", __func__,
17526 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
17527 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017528 }
17529
Atul Mittal115287b2014-07-08 13:26:33 +053017530 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
17531
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017532 mutex_unlock(&pHddCtx->tdls_lock);
17533
Atul Mittal115287b2014-07-08 13:26:33 +053017534 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17535 " %s TDLS Add Force Peer Failed",
17536 __func__);
17537 return -EINVAL;
17538 }
17539 /*EXT TDLS*/
17540
17541 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017542 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17544 " %s TDLS set callback Failed",
17545 __func__);
17546 return -EINVAL;
17547 }
17548
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017549 mutex_unlock(&pHddCtx->tdls_lock);
17550
Atul Mittal115287b2014-07-08 13:26:33 +053017551 return(0);
17552
17553}
17554
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017555int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
17556#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17557 const u8 *peer
17558#else
17559 u8 *peer
17560#endif
17561)
Atul Mittal115287b2014-07-08 13:26:33 +053017562{
17563
17564 hddTdlsPeer_t *pTdlsPeer;
17565 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17566 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17567 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
17568 __func__, MAC_ADDR_ARRAY(peer));
17569
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017570 if (0 != wlan_hdd_validate_context(pHddCtx)) {
17571 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
17572 return -EINVAL;
17573 }
17574
Atul Mittal115287b2014-07-08 13:26:33 +053017575 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
17576 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
17577
17578 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017579 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
17580 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
17581 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053017582 return -ENOTSUPP;
17583 }
17584
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017585 mutex_lock(&pHddCtx->tdls_lock);
17586 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Atul Mittal115287b2014-07-08 13:26:33 +053017587
17588 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017589 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017590 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017591 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053017592 __func__, MAC_ADDR_ARRAY(peer));
17593 return -EINVAL;
17594 }
17595 else {
17596 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
17597 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017598 /* if channel switch is configured, reset
17599 the channel for this peer */
17600 if (TRUE == pTdlsPeer->isOffChannelConfigured)
17601 {
17602 pTdlsPeer->peerParams.channel = 0;
17603 pTdlsPeer->isOffChannelConfigured = FALSE;
17604 }
Atul Mittal115287b2014-07-08 13:26:33 +053017605 }
17606
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017607 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017608 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017609 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053017610 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017611 }
Atul Mittal115287b2014-07-08 13:26:33 +053017612
17613 /*EXT TDLS*/
17614
17615 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017616 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053017617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17618 " %s TDLS set callback Failed",
17619 __func__);
17620 return -EINVAL;
17621 }
Atul Mittal115287b2014-07-08 13:26:33 +053017622
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017623 mutex_unlock(&pHddCtx->tdls_lock);
17624
17625 return(0);
Atul Mittal115287b2014-07-08 13:26:33 +053017626}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017627static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053017628#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
17629 const u8 *peer,
17630#else
17631 u8 *peer,
17632#endif
17633 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017634{
17635 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17636 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017637 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017638 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017639
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017640 ENTER();
17641
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053017642 if (!pAdapter) {
17643 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
17644 return -EINVAL;
17645 }
17646
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017647 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17648 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
17649 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017650 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017651 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080017652 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070017653 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017654 return -EINVAL;
17655 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017656
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017657 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017658 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017659 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017660 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080017661 }
17662
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017663
17664 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017665 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017666 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080017667 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017668 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
17669 "Cannot process TDLS commands",
17670 pHddCtx->cfg_ini->fEnableTDLSSupport,
17671 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017672 return -ENOTSUPP;
17673 }
17674
17675 switch (oper) {
17676 case NL80211_TDLS_ENABLE_LINK:
17677 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017678 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017679 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017680 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053017681 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017682 tANI_U16 numCurrTdlsPeers = 0;
17683 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017684 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017685
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017686 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17687 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
17688 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017689
Sunil Dutt41de4e22013-11-14 18:09:02 +053017690 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053017691 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053017692 if ( NULL == pTdlsPeer ) {
17693 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
17694 " (oper %d) not exsting. ignored",
17695 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
17696 return -EINVAL;
17697 }
17698
17699 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17700 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
17701 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
17702 "NL80211_TDLS_ENABLE_LINK");
17703
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070017704 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
17705 {
17706 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
17707 MAC_ADDRESS_STR " failed",
17708 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
17709 return -EINVAL;
17710 }
17711
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053017712 /* before starting tdls connection, set tdls
17713 * off channel established status to default value */
17714 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017715 /* TDLS Off Channel, Disable tdls channel switch,
17716 when there are more than one tdls link */
17717 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053017718 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017719 {
17720 /* get connected peer and send disable tdls off chan */
17721 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017722 if ((connPeer) &&
17723 (connPeer->isOffChannelSupported == TRUE) &&
17724 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017725 {
17726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17727 "%s: More then one peer connected, Disable "
17728 "TDLS channel switch", __func__);
17729
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053017730 connPeer->isOffChannelEstablished = FALSE;
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017731
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017732 ret = sme_SendTdlsChanSwitchReq(
17733 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017734 pAdapter->sessionId,
17735 connPeer->peerMac,
17736 connPeer->peerParams.channel,
17737 TDLS_OFF_CHANNEL_BW_OFFSET,
17738 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017739 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017740 hddLog(VOS_TRACE_LEVEL_ERROR,
17741 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017742 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017743 }
17744 else
17745 {
17746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17747 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017748 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017749 "isOffChannelConfigured %d",
17750 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017751 (connPeer ? (connPeer->isOffChannelSupported)
17752 : -1),
17753 (connPeer ? (connPeer->isOffChannelConfigured)
17754 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017755 }
17756 }
17757
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017758 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017759 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017760 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053017761
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017762 if (0 != wlan_hdd_tdls_get_link_establish_params(
17763 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017764 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017765 return -EINVAL;
17766 }
17767 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017768
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017769 ret = sme_SendTdlsLinkEstablishParams(
17770 WLAN_HDD_GET_HAL_CTX(pAdapter),
17771 pAdapter->sessionId, peer,
17772 &tdlsLinkEstablishParams);
17773 if (ret != VOS_STATUS_SUCCESS) {
17774 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
17775 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017776 /* Send TDLS peer UAPSD capabilities to the firmware and
17777 * register with the TL on after the response for this operation
17778 * is received .
17779 */
17780 ret = wait_for_completion_interruptible_timeout(
17781 &pAdapter->tdls_link_establish_req_comp,
17782 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
17783 if (ret <= 0)
17784 {
17785 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017786 FL("Link Establish Request Failed Status %ld"),
17787 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053017788 return -EINVAL;
17789 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017790 }
Masti, Narayanraddi6b93b472015-09-04 17:48:11 +053017791
Atul Mittal115287b2014-07-08 13:26:33 +053017792 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
17793 eTDLS_LINK_CONNECTED,
17794 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053017795 staDesc.ucSTAId = pTdlsPeer->staId;
17796 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017797 ret = WLANTL_UpdateTdlsSTAClient(
17798 pHddCtx->pvosContext,
17799 &staDesc);
17800 if (ret != VOS_STATUS_SUCCESS) {
17801 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
17802 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053017803
Gopichand Nakkala471708b2013-06-04 20:03:01 +053017804 /* Mark TDLS client Authenticated .*/
17805 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
17806 pTdlsPeer->staId,
17807 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070017808 if (VOS_STATUS_SUCCESS == status)
17809 {
Hoonki Lee14621352013-04-16 17:51:19 -070017810 if (pTdlsPeer->is_responder == 0)
17811 {
17812 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053017813 tdlsConnInfo_t *tdlsInfo;
17814
17815 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
17816
17817 /* Initialize initiator wait callback */
17818 vos_timer_init(
17819 &pTdlsPeer->initiatorWaitTimeoutTimer,
17820 VOS_TIMER_TYPE_SW,
17821 wlan_hdd_tdls_initiator_wait_cb,
17822 tdlsInfo);
Hoonki Lee14621352013-04-16 17:51:19 -070017823
17824 wlan_hdd_tdls_timer_restart(pAdapter,
17825 &pTdlsPeer->initiatorWaitTimeoutTimer,
17826 WAIT_TIME_TDLS_INITIATOR);
17827 /* suspend initiator TX until it receives direct packet from the
17828 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017829 ret = WLANTL_SuspendDataTx(
17830 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
17831 &staId, NULL);
17832 if (ret != VOS_STATUS_SUCCESS) {
17833 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
17834 }
Hoonki Lee14621352013-04-16 17:51:19 -070017835 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017836
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017837 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017838 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017839 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017840 suppChannelLen =
17841 tdlsLinkEstablishParams.supportedChannelsLen;
17842
17843 if ((suppChannelLen > 0) &&
17844 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
17845 {
17846 tANI_U8 suppPeerChannel = 0;
17847 int i = 0;
17848 for (i = 0U; i < suppChannelLen; i++)
17849 {
17850 suppPeerChannel =
17851 tdlsLinkEstablishParams.supportedChannels[i];
17852
17853 pTdlsPeer->isOffChannelSupported = FALSE;
17854 if (suppPeerChannel ==
17855 pTdlsPeer->peerParams.channel)
17856 {
17857 pTdlsPeer->isOffChannelSupported = TRUE;
17858 break;
17859 }
17860 }
17861 }
17862 else
17863 {
17864 pTdlsPeer->isOffChannelSupported = FALSE;
17865 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017866 }
17867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17868 "%s: TDLS channel switch request for channel "
17869 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017870 "%d isOffChannelSupported %d", __func__,
17871 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017872 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053017873 suppChannelLen,
17874 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053017875
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017876 /* TDLS Off Channel, Enable tdls channel switch,
17877 when their is only one tdls link and it supports */
17878 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
17879 if ((numCurrTdlsPeers == 1) &&
17880 (TRUE == pTdlsPeer->isOffChannelSupported) &&
17881 (TRUE == pTdlsPeer->isOffChannelConfigured))
17882 {
17883 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17884 "%s: Send TDLS channel switch request for channel %d",
17885 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053017886
17887 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017888 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
17889 pAdapter->sessionId,
17890 pTdlsPeer->peerMac,
17891 pTdlsPeer->peerParams.channel,
17892 TDLS_OFF_CHANNEL_BW_OFFSET,
17893 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017894 if (ret != VOS_STATUS_SUCCESS) {
17895 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
17896 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017897 }
17898 else
17899 {
17900 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17901 "%s: TDLS channel switch request not sent"
17902 " numCurrTdlsPeers %d "
17903 "isOffChannelSupported %d "
17904 "isOffChannelConfigured %d",
17905 __func__, numCurrTdlsPeers,
17906 pTdlsPeer->isOffChannelSupported,
17907 pTdlsPeer->isOffChannelConfigured);
17908 }
17909
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070017910 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017911 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017912
17913 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053017914 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
17915 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017916 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053017917 int ac;
17918 uint8 ucAc[4] = { WLANTL_AC_VO,
17919 WLANTL_AC_VI,
17920 WLANTL_AC_BK,
17921 WLANTL_AC_BE };
17922 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
17923 for(ac=0; ac < 4; ac++)
17924 {
17925 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
17926 pTdlsPeer->staId, ucAc[ac],
17927 tlTid[ac], tlTid[ac], 0, 0,
17928 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017929 if (status != VOS_STATUS_SUCCESS) {
17930 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
17931 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053017932 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053017933 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070017934 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017935 }
17936 break;
17937 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080017938 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053017939 tANI_U16 numCurrTdlsPeers = 0;
17940 hddTdlsPeer_t *connPeer = NULL;
17941
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017942 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17943 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
17944 __func__, MAC_ADDR_ARRAY(peer));
17945
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053017946 mutex_lock(&pHddCtx->tdls_lock);
17947 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
Sunil Dutt41de4e22013-11-14 18:09:02 +053017948
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053017949
Sunil Dutt41de4e22013-11-14 18:09:02 +053017950 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053017951 mutex_unlock(&pHddCtx->tdls_lock);
Sunil Dutt41de4e22013-11-14 18:09:02 +053017952 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
17953 " (oper %d) not exsting. ignored",
17954 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
17955 return -EINVAL;
17956 }
17957
17958 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17959 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
17960 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
17961 "NL80211_TDLS_DISABLE_LINK");
17962
Hoonki Lee5305c3a2013-04-29 23:28:59 -070017963 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080017964 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017965 long status;
17966
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053017967 /* set tdls off channel status to false for this peer */
17968 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053017969 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
17970 eTDLS_LINK_TEARING,
17971 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
17972 eTDLS_LINK_UNSPECIFIED:
17973 eTDLS_LINK_DROPPED_BY_REMOTE);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053017974 mutex_unlock(&pHddCtx->tdls_lock);
17975
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017976 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
17977
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053017978 status = sme_DeleteTdlsPeerSta(
17979 WLAN_HDD_GET_HAL_CTX(pAdapter),
17980 pAdapter->sessionId, peer );
17981 if (status != VOS_STATUS_SUCCESS) {
17982 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
17983 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070017984
17985 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
17986 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053017987
17988 mutex_lock(&pHddCtx->tdls_lock);
17989 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
17990 if ( NULL == pTdlsPeer ) {
17991 mutex_unlock(&pHddCtx->tdls_lock);
17992 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
17993 " peer was freed in other context",
17994 __func__, MAC_ADDR_ARRAY(peer));
17995 return -EINVAL;
17996 }
17997
Atul Mittal271a7652014-09-12 13:18:22 +053017998 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053017999 eTDLS_LINK_IDLE,
18000 eTDLS_LINK_UNSPECIFIED);
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018001 mutex_unlock(&pHddCtx->tdls_lock);
18002
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018003 if (status <= 0)
18004 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070018005 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18006 "%s: Del station failed status %ld",
18007 __func__, status);
18008 return -EPERM;
18009 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018010
18011 /* TDLS Off Channel, Enable tdls channel switch,
18012 when their is only one tdls link and it supports */
18013 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
18014 if (numCurrTdlsPeers == 1)
18015 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018016 tSirMacAddr peerMac;
18017 int channel;
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018018
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018019 mutex_lock(&pHddCtx->tdls_lock);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018020 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Masti, Narayanraddi3818aea2015-10-17 15:20:28 +053018021
18022 if (connPeer == NULL) {
18023 mutex_unlock(&pHddCtx->tdls_lock);
18024 hddLog(VOS_TRACE_LEVEL_ERROR,
18025 "%s connPeer is NULL", __func__);
18026 return -EINVAL;
18027 }
18028
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018029 vos_mem_copy(peerMac, connPeer->peerMac, sizeof(tSirMacAddr));
18030 channel = connPeer->peerParams.channel;
18031
18032 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18033 "%s: TDLS channel switch "
18034 "isOffChannelSupported %d "
18035 "isOffChannelConfigured %d "
18036 "isOffChannelEstablished %d",
18037 __func__,
18038 (connPeer ? connPeer->isOffChannelSupported : -1),
18039 (connPeer ? connPeer->isOffChannelConfigured : -1),
18040 (connPeer ? connPeer->isOffChannelEstablished : -1));
18041
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018042 if ((connPeer) &&
18043 (connPeer->isOffChannelSupported == TRUE) &&
18044 (connPeer->isOffChannelConfigured == TRUE))
18045 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053018046 connPeer->isOffChannelEstablished = TRUE;
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018047 mutex_unlock(&pHddCtx->tdls_lock);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018048 status = sme_SendTdlsChanSwitchReq(
18049 WLAN_HDD_GET_HAL_CTX(pAdapter),
18050 pAdapter->sessionId,
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018051 peerMac,
18052 channel,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053018053 TDLS_OFF_CHANNEL_BW_OFFSET,
18054 TDLS_CHANNEL_SWITCH_ENABLE);
18055 if (status != VOS_STATUS_SUCCESS) {
18056 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
18057 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018058 }
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018059 else
18060 mutex_unlock(&pHddCtx->tdls_lock);
18061 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018062 else
18063 {
18064 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18065 "%s: TDLS channel switch request not sent "
18066 "numCurrTdlsPeers %d ",
18067 __func__, numCurrTdlsPeers);
18068 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018069 }
18070 else
18071 {
Masti, Narayanraddi8208f062015-10-15 13:16:17 +053018072 mutex_unlock(&pHddCtx->tdls_lock);
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18074 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080018075 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080018076 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070018077 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018078 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018079 {
Atul Mittal115287b2014-07-08 13:26:33 +053018080 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018081
Atul Mittal115287b2014-07-08 13:26:33 +053018082 if (0 != status)
18083 {
18084 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018085 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053018086 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018087 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053018088 break;
18089 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018090 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053018091 {
Atul Mittal115287b2014-07-08 13:26:33 +053018092 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
18093 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053018094 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053018095 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053018096
Atul Mittal115287b2014-07-08 13:26:33 +053018097 if (0 != status)
18098 {
18099 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018100 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053018101 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053018102 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053018103 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053018104 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018105 case NL80211_TDLS_DISCOVERY_REQ:
18106 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018107 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053018108 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018109 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018110 return -ENOTSUPP;
18111 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18113 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018114 return -ENOTSUPP;
18115 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018116
18117 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018118 return 0;
18119}
Chilam NG571c65a2013-01-19 12:27:36 +053018120
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018121static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018122#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
18123 const u8 *peer,
18124#else
18125 u8 *peer,
18126#endif
18127 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018128{
18129 int ret;
18130
18131 vos_ssr_protect(__func__);
18132 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
18133 vos_ssr_unprotect(__func__);
18134
18135 return ret;
18136}
18137
Chilam NG571c65a2013-01-19 12:27:36 +053018138int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
18139 struct net_device *dev, u8 *peer)
18140{
Arif Hussaina7c8e412013-11-20 11:06:42 -080018141 hddLog(VOS_TRACE_LEVEL_INFO,
18142 "tdls send discover req: "MAC_ADDRESS_STR,
18143 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053018144
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018145#if TDLS_MGMT_VERSION2
18146 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18147 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18148#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018149#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
18150 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18151 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
18152#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
18153 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18154 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18155#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
18156 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18157 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
18158#else
Chilam NG571c65a2013-01-19 12:27:36 +053018159 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
18160 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053018161#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053018162#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053018163}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018164#endif
18165
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018166#ifdef WLAN_FEATURE_GTK_OFFLOAD
18167/*
18168 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
18169 * Callback rountine called upon receiving response for
18170 * get offload info
18171 */
18172void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
18173 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
18174{
18175
18176 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018177 tANI_U8 tempReplayCounter[8];
18178 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018179
18180 ENTER();
18181
18182 if (NULL == pAdapter)
18183 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053018184 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018185 "%s: HDD adapter is Null", __func__);
18186 return ;
18187 }
18188
18189 if (NULL == pGtkOffloadGetInfoRsp)
18190 {
18191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18192 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
18193 return ;
18194 }
18195
18196 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
18197 {
18198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18199 "%s: wlan Failed to get replay counter value",
18200 __func__);
18201 return ;
18202 }
18203
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018204 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18205 /* Update replay counter */
18206 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
18207 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18208
18209 {
18210 /* changing from little to big endian since supplicant
18211 * works on big endian format
18212 */
18213 int i;
18214 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
18215
18216 for (i = 0; i < 8; i++)
18217 {
18218 tempReplayCounter[7-i] = (tANI_U8)p[i];
18219 }
18220 }
18221
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018222 /* Update replay counter to NL */
18223 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018224 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018225}
18226
18227/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018228 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018229 * This function is used to offload GTK rekeying job to the firmware.
18230 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018231int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018232 struct cfg80211_gtk_rekey_data *data)
18233{
18234 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18235 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
18236 hdd_station_ctx_t *pHddStaCtx;
18237 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018238 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018239 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018240 eHalStatus status = eHAL_STATUS_FAILURE;
18241
18242 ENTER();
18243
18244 if (NULL == pAdapter)
18245 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053018246 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018247 "%s: HDD adapter is Null", __func__);
18248 return -ENODEV;
18249 }
18250
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053018251 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18252 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
18253 pAdapter->sessionId, pAdapter->device_mode));
18254
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018255 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018256 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018257 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053018258 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018259 }
18260
18261 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18262 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
18263 if (NULL == hHal)
18264 {
18265 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18266 "%s: HAL context is Null!!!", __func__);
18267 return -EAGAIN;
18268 }
18269
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018270 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
18271 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
18272 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
18273 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018274 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018275 {
18276 /* changing from big to little endian since driver
18277 * works on little endian format
18278 */
18279 tANI_U8 *p =
18280 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
18281 int i;
18282
18283 for (i = 0; i < 8; i++)
18284 {
18285 p[7-i] = data->replay_ctr[i];
18286 }
18287 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018288
18289 if (TRUE == pHddCtx->hdd_wlan_suspended)
18290 {
18291 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018292 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
18293 sizeof (tSirGtkOffloadParams));
18294 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018295 pAdapter->sessionId);
18296
18297 if (eHAL_STATUS_SUCCESS != status)
18298 {
18299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18300 "%s: sme_SetGTKOffload failed, returned %d",
18301 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018302
18303 /* Need to clear any trace of key value in the memory.
18304 * Thus zero out the memory even though it is local
18305 * variable.
18306 */
18307 vos_mem_zero(&hddGtkOffloadReqParams,
18308 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018309 return status;
18310 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018311 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18312 "%s: sme_SetGTKOffload successfull", __func__);
18313 }
18314 else
18315 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018316 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18317 "%s: wlan not suspended GTKOffload request is stored",
18318 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018319 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018320
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053018321 /* Need to clear any trace of key value in the memory.
18322 * Thus zero out the memory even though it is local
18323 * variable.
18324 */
18325 vos_mem_zero(&hddGtkOffloadReqParams,
18326 sizeof(hddGtkOffloadReqParams));
18327
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018328 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053018329 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018330}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018331
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018332int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
18333 struct cfg80211_gtk_rekey_data *data)
18334{
18335 int ret;
18336
18337 vos_ssr_protect(__func__);
18338 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
18339 vos_ssr_unprotect(__func__);
18340
18341 return ret;
18342}
18343#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018344/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018345 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018346 * This function is used to set access control policy
18347 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018348static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18349 struct net_device *dev,
18350 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018351{
18352 int i;
18353 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18354 hdd_hostapd_state_t *pHostapdState;
18355 tsap_Config_t *pConfig;
18356 v_CONTEXT_t pVosContext = NULL;
18357 hdd_context_t *pHddCtx;
18358 int status;
18359
18360 ENTER();
18361
18362 if (NULL == pAdapter)
18363 {
18364 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18365 "%s: HDD adapter is Null", __func__);
18366 return -ENODEV;
18367 }
18368
18369 if (NULL == params)
18370 {
18371 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18372 "%s: params is Null", __func__);
18373 return -EINVAL;
18374 }
18375
18376 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18377 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018378 if (0 != status)
18379 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018380 return status;
18381 }
18382
18383 pVosContext = pHddCtx->pvosContext;
18384 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
18385
18386 if (NULL == pHostapdState)
18387 {
18388 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18389 "%s: pHostapdState is Null", __func__);
18390 return -EINVAL;
18391 }
18392
18393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
18394 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018395 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18396 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
18397 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018398
18399 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
18400 {
18401 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
18402
18403 /* default value */
18404 pConfig->num_accept_mac = 0;
18405 pConfig->num_deny_mac = 0;
18406
18407 /**
18408 * access control policy
18409 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
18410 * listed in hostapd.deny file.
18411 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
18412 * listed in hostapd.accept file.
18413 */
18414 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
18415 {
18416 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
18417 }
18418 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
18419 {
18420 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
18421 }
18422 else
18423 {
18424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18425 "%s:Acl Policy : %d is not supported",
18426 __func__, params->acl_policy);
18427 return -ENOTSUPP;
18428 }
18429
18430 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
18431 {
18432 pConfig->num_accept_mac = params->n_acl_entries;
18433 for (i = 0; i < params->n_acl_entries; i++)
18434 {
18435 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18436 "** Add ACL MAC entry %i in WhiletList :"
18437 MAC_ADDRESS_STR, i,
18438 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18439
18440 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
18441 sizeof(qcmacaddr));
18442 }
18443 }
18444 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
18445 {
18446 pConfig->num_deny_mac = params->n_acl_entries;
18447 for (i = 0; i < params->n_acl_entries; i++)
18448 {
18449 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18450 "** Add ACL MAC entry %i in BlackList :"
18451 MAC_ADDRESS_STR, i,
18452 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
18453
18454 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
18455 sizeof(qcmacaddr));
18456 }
18457 }
18458
18459 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
18460 {
18461 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18462 "%s: SAP Set Mac Acl fail", __func__);
18463 return -EINVAL;
18464 }
18465 }
18466 else
18467 {
18468 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053018469 "%s: Invalid device_mode = %s (%d)",
18470 __func__, hdd_device_modetoString(pAdapter->device_mode),
18471 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018472 return -EINVAL;
18473 }
18474
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018475 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018476 return 0;
18477}
18478
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053018479static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
18480 struct net_device *dev,
18481 const struct cfg80211_acl_data *params)
18482{
18483 int ret;
18484 vos_ssr_protect(__func__);
18485 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
18486 vos_ssr_unprotect(__func__);
18487
18488 return ret;
18489}
18490
Leo Chang9056f462013-08-01 19:21:11 -070018491#ifdef WLAN_NL80211_TESTMODE
18492#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070018493void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070018494(
18495 void *pAdapter,
18496 void *indCont
18497)
18498{
Leo Changd9df8aa2013-09-26 13:32:26 -070018499 tSirLPHBInd *lphbInd;
18500 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053018501 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070018502
18503 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070018504 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070018505
c_hpothu73f35e62014-04-18 13:40:08 +053018506 if (pAdapter == NULL)
18507 {
18508 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18509 "%s: pAdapter is NULL\n",__func__);
18510 return;
18511 }
18512
Leo Chang9056f462013-08-01 19:21:11 -070018513 if (NULL == indCont)
18514 {
18515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070018516 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070018517 return;
18518 }
18519
c_hpothu73f35e62014-04-18 13:40:08 +053018520 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070018521 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070018522 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053018523 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070018524 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070018525 GFP_ATOMIC);
18526 if (!skb)
18527 {
18528 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18529 "LPHB timeout, NL buffer alloc fail");
18530 return;
18531 }
18532
Leo Changac3ba772013-10-07 09:47:04 -070018533 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070018534 {
18535 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18536 "WLAN_HDD_TM_ATTR_CMD put fail");
18537 goto nla_put_failure;
18538 }
Leo Changac3ba772013-10-07 09:47:04 -070018539 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070018540 {
18541 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18542 "WLAN_HDD_TM_ATTR_TYPE put fail");
18543 goto nla_put_failure;
18544 }
Leo Changac3ba772013-10-07 09:47:04 -070018545 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070018546 sizeof(tSirLPHBInd), lphbInd))
18547 {
18548 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18549 "WLAN_HDD_TM_ATTR_DATA put fail");
18550 goto nla_put_failure;
18551 }
Leo Chang9056f462013-08-01 19:21:11 -070018552 cfg80211_testmode_event(skb, GFP_ATOMIC);
18553 return;
18554
18555nla_put_failure:
18556 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18557 "NLA Put fail");
18558 kfree_skb(skb);
18559
18560 return;
18561}
18562#endif /* FEATURE_WLAN_LPHB */
18563
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018564static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070018565{
18566 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
18567 int err = 0;
18568#ifdef FEATURE_WLAN_LPHB
18569 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070018570 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018571
18572 ENTER();
18573
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018574 err = wlan_hdd_validate_context(pHddCtx);
18575 if (0 != err)
18576 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018577 return err;
18578 }
Leo Chang9056f462013-08-01 19:21:11 -070018579#endif /* FEATURE_WLAN_LPHB */
18580
18581 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
18582 if (err)
18583 {
18584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18585 "%s Testmode INV ATTR", __func__);
18586 return err;
18587 }
18588
18589 if (!tb[WLAN_HDD_TM_ATTR_CMD])
18590 {
18591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18592 "%s Testmode INV CMD", __func__);
18593 return -EINVAL;
18594 }
18595
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018596 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18597 TRACE_CODE_HDD_CFG80211_TESTMODE,
18598 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070018599 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
18600 {
18601#ifdef FEATURE_WLAN_LPHB
18602 /* Low Power Heartbeat configuration request */
18603 case WLAN_HDD_TM_CMD_WLAN_HB:
18604 {
18605 int buf_len;
18606 void *buf;
18607 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080018608 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070018609
18610 if (!tb[WLAN_HDD_TM_ATTR_DATA])
18611 {
18612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18613 "%s Testmode INV DATA", __func__);
18614 return -EINVAL;
18615 }
18616
18617 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
18618 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080018619
18620 hb_params_temp =(tSirLPHBReq *)buf;
18621 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
18622 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
18623 return -EINVAL;
18624
Leo Chang9056f462013-08-01 19:21:11 -070018625 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
18626 if (NULL == hb_params)
18627 {
18628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18629 "%s Request Buffer Alloc Fail", __func__);
18630 return -EINVAL;
18631 }
18632
18633 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070018634 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
18635 hb_params,
18636 wlan_hdd_cfg80211_lphb_ind_handler);
18637 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070018638 {
Leo Changd9df8aa2013-09-26 13:32:26 -070018639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18640 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070018641 vos_mem_free(hb_params);
18642 }
Leo Chang9056f462013-08-01 19:21:11 -070018643 return 0;
18644 }
18645#endif /* FEATURE_WLAN_LPHB */
18646 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053018647 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
18648 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070018649 return -EOPNOTSUPP;
18650 }
18651
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018652 EXIT();
18653 return err;
Leo Chang9056f462013-08-01 19:21:11 -070018654}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018655
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053018656static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
18657#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
18658 struct wireless_dev *wdev,
18659#endif
18660 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018661{
18662 int ret;
18663
18664 vos_ssr_protect(__func__);
18665 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
18666 vos_ssr_unprotect(__func__);
18667
18668 return ret;
18669}
Leo Chang9056f462013-08-01 19:21:11 -070018670#endif /* CONFIG_NL80211_TESTMODE */
18671
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018672static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018673 struct net_device *dev,
18674 int idx, struct survey_info *survey)
18675{
18676 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
18677 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053018678 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018679 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053018680 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018681 v_S7_t snr,rssi;
18682 int status, i, j, filled = 0;
18683
18684 ENTER();
18685
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018686 if (NULL == pAdapter)
18687 {
18688 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18689 "%s: HDD adapter is Null", __func__);
18690 return -ENODEV;
18691 }
18692
18693 if (NULL == wiphy)
18694 {
18695 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
18696 "%s: wiphy is Null", __func__);
18697 return -ENODEV;
18698 }
18699
18700 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
18701 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018702 if (0 != status)
18703 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018704 return status;
18705 }
18706
Mihir Sheted9072e02013-08-21 17:02:29 +053018707 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
18708
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018709 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053018710 0 != pAdapter->survey_idx ||
18711 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018712 {
18713 /* The survey dump ops when implemented completely is expected to
18714 * return a survey of all channels and the ops is called by the
18715 * kernel with incremental values of the argument 'idx' till it
18716 * returns -ENONET. But we can only support the survey for the
18717 * operating channel for now. survey_idx is used to track
18718 * that the ops is called only once and then return -ENONET for
18719 * the next iteration
18720 */
18721 pAdapter->survey_idx = 0;
18722 return -ENONET;
18723 }
18724
Mukul Sharma9d5233b2015-06-11 20:28:20 +053018725 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
18726 {
18727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18728 "%s: Roaming in progress, hence return ", __func__);
18729 return -ENONET;
18730 }
18731
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018732 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
18733
18734 wlan_hdd_get_snr(pAdapter, &snr);
18735 wlan_hdd_get_rssi(pAdapter, &rssi);
18736
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018737 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18738 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
18739 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018740 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
18741 hdd_wlan_get_freq(channel, &freq);
18742
18743
18744 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
18745 {
18746 if (NULL == wiphy->bands[i])
18747 {
18748 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
18749 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
18750 continue;
18751 }
18752
18753 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
18754 {
18755 struct ieee80211_supported_band *band = wiphy->bands[i];
18756
18757 if (band->channels[j].center_freq == (v_U16_t)freq)
18758 {
18759 survey->channel = &band->channels[j];
18760 /* The Rx BDs contain SNR values in dB for the received frames
18761 * while the supplicant expects noise. So we calculate and
18762 * return the value of noise (dBm)
18763 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
18764 */
18765 survey->noise = rssi - snr;
18766 survey->filled = SURVEY_INFO_NOISE_DBM;
18767 filled = 1;
18768 }
18769 }
18770 }
18771
18772 if (filled)
18773 pAdapter->survey_idx = 1;
18774 else
18775 {
18776 pAdapter->survey_idx = 0;
18777 return -ENONET;
18778 }
18779
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018780 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018781 return 0;
18782}
18783
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053018784static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
18785 struct net_device *dev,
18786 int idx, struct survey_info *survey)
18787{
18788 int ret;
18789
18790 vos_ssr_protect(__func__);
18791 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
18792 vos_ssr_unprotect(__func__);
18793
18794 return ret;
18795}
18796
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018797/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018798 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018799 * this is called when cfg80211 driver resume
18800 * driver updates latest sched_scan scan result(if any) to cfg80211 database
18801 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018802int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018803{
18804 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
18805 hdd_adapter_t *pAdapter;
18806 hdd_adapter_list_node_t *pAdapterNode, *pNext;
18807 VOS_STATUS status = VOS_STATUS_SUCCESS;
18808
18809 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018810
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053018811 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018812 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018813 return 0;
18814 }
18815
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018816 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
18817 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018818 spin_lock(&pHddCtx->schedScan_lock);
18819 pHddCtx->isWiphySuspended = FALSE;
18820 if (TRUE != pHddCtx->isSchedScanUpdatePending)
18821 {
18822 spin_unlock(&pHddCtx->schedScan_lock);
18823 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18824 "%s: Return resume is not due to PNO indication", __func__);
18825 return 0;
18826 }
18827 // Reset flag to avoid updatating cfg80211 data old results again
18828 pHddCtx->isSchedScanUpdatePending = FALSE;
18829 spin_unlock(&pHddCtx->schedScan_lock);
18830
18831 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
18832
18833 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
18834 {
18835 pAdapter = pAdapterNode->pAdapter;
18836 if ( (NULL != pAdapter) &&
18837 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
18838 {
18839 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018840 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018841 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
18842 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018843 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018844 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018845 {
18846 /* Acquire wakelock to handle the case where APP's tries to
18847 * suspend immediately after updating the scan results. Whis
18848 * results in app's is in suspended state and not able to
18849 * process the connect request to AP
18850 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053018851 hdd_prevent_suspend_timeout(2000,
18852 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018853 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053018854 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018855
18856 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18857 "%s : cfg80211 scan result database updated", __func__);
18858
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018859 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018860 return 0;
18861
18862 }
18863 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
18864 pAdapterNode = pNext;
18865 }
18866
18867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
18868 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018869 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018870 return 0;
18871}
18872
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018873int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
18874{
18875 int ret;
18876
18877 vos_ssr_protect(__func__);
18878 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
18879 vos_ssr_unprotect(__func__);
18880
18881 return ret;
18882}
18883
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018884/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018885 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018886 * this is called when cfg80211 driver suspends
18887 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018888int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018889 struct cfg80211_wowlan *wow)
18890{
18891 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018892 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018893
18894 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053018895
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018896 ret = wlan_hdd_validate_context(pHddCtx);
18897 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018898 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018899 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018900 }
18901
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053018902
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053018903 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
18904 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
18905 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018906 pHddCtx->isWiphySuspended = TRUE;
18907
18908 EXIT();
18909
18910 return 0;
18911}
18912
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053018913int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
18914 struct cfg80211_wowlan *wow)
18915{
18916 int ret;
18917
18918 vos_ssr_protect(__func__);
18919 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
18920 vos_ssr_unprotect(__func__);
18921
18922 return ret;
18923}
Jeff Johnson295189b2012-06-20 16:38:30 -070018924/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053018925static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070018926{
18927 .add_virtual_intf = wlan_hdd_add_virtual_intf,
18928 .del_virtual_intf = wlan_hdd_del_virtual_intf,
18929 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
18930 .change_station = wlan_hdd_change_station,
18931#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
18932 .add_beacon = wlan_hdd_cfg80211_add_beacon,
18933 .del_beacon = wlan_hdd_cfg80211_del_beacon,
18934 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018935#else
18936 .start_ap = wlan_hdd_cfg80211_start_ap,
18937 .change_beacon = wlan_hdd_cfg80211_change_beacon,
18938 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070018939#endif
18940 .change_bss = wlan_hdd_cfg80211_change_bss,
18941 .add_key = wlan_hdd_cfg80211_add_key,
18942 .get_key = wlan_hdd_cfg80211_get_key,
18943 .del_key = wlan_hdd_cfg80211_del_key,
18944 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080018945#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070018946 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080018947#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018948 .scan = wlan_hdd_cfg80211_scan,
18949 .connect = wlan_hdd_cfg80211_connect,
18950 .disconnect = wlan_hdd_cfg80211_disconnect,
18951 .join_ibss = wlan_hdd_cfg80211_join_ibss,
18952 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
18953 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
18954 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
18955 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070018956 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
18957 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053018958 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070018959#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
18960 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
18961 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
18962 .set_txq_params = wlan_hdd_set_txq_params,
18963#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070018964 .get_station = wlan_hdd_cfg80211_get_station,
18965 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
18966 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070018967 .add_station = wlan_hdd_cfg80211_add_station,
18968#ifdef FEATURE_WLAN_LFR
18969 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
18970 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
18971 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
18972#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070018973#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
18974 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
18975#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080018976#ifdef FEATURE_WLAN_TDLS
18977 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
18978 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
18979#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053018980#ifdef WLAN_FEATURE_GTK_OFFLOAD
18981 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
18982#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053018983#ifdef FEATURE_WLAN_SCAN_PNO
18984 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
18985 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
18986#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053018987 .resume = wlan_hdd_cfg80211_resume_wlan,
18988 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053018989 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070018990#ifdef WLAN_NL80211_TESTMODE
18991 .testmode_cmd = wlan_hdd_cfg80211_testmode,
18992#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053018993 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070018994};
18995