blob: 6e1e29d2214c977468be82f033f58f71182db701 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +053098#include "qwlan_version.h"
c_manjeecfd1efb2015-09-25 19:32:34 +053099#include "wlan_logging_sock_svc.h"
Sushant Kaushik084f6592015-09-10 13:11:56 +0530100
Jeff Johnson295189b2012-06-20 16:38:30 -0700101
102#define g_mode_rates_size (12)
103#define a_mode_rates_size (8)
104#define FREQ_BASE_80211G (2407)
105#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700106#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530107#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700108#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800109 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700110
111#define HDD2GHZCHAN(freq, chan, flag) { \
112 .band = IEEE80211_BAND_2GHZ, \
113 .center_freq = (freq), \
114 .hw_value = (chan),\
115 .flags = (flag), \
116 .max_antenna_gain = 0 ,\
117 .max_power = 30, \
118}
119
120#define HDD5GHZCHAN(freq, chan, flag) { \
121 .band = IEEE80211_BAND_5GHZ, \
122 .center_freq = (freq), \
123 .hw_value = (chan),\
124 .flags = (flag), \
125 .max_antenna_gain = 0 ,\
126 .max_power = 30, \
127}
128
129#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
130{\
131 .bitrate = rate, \
132 .hw_value = rate_id, \
133 .flags = flag, \
134}
135
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530136#ifdef WLAN_FEATURE_VOWIFI_11R
137#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
138#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
139#endif
140
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530141#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530142#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530143
Sunil Duttc69bccb2014-05-26 21:30:20 +0530144#ifdef WLAN_FEATURE_LINK_LAYER_STATS
145/*
146 * Used to allocate the size of 4096 for the link layer stats.
147 * The size of 4096 is considered assuming that all data per
148 * respective event fit with in the limit.Please take a call
149 * on the limit based on the data requirements on link layer
150 * statistics.
151 */
152#define LL_STATS_EVENT_BUF_SIZE 4096
153#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530154#ifdef WLAN_FEATURE_EXTSCAN
155/*
156 * Used to allocate the size of 4096 for the EXTScan NL data.
157 * The size of 4096 is considered assuming that all data per
158 * respective event fit with in the limit.Please take a call
159 * on the limit based on the data requirements.
160 */
161
162#define EXTSCAN_EVENT_BUF_SIZE 4096
163#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
164#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530165
Atul Mittal115287b2014-07-08 13:26:33 +0530166/*EXT TDLS*/
167/*
168 * Used to allocate the size of 4096 for the TDLS.
169 * The size of 4096 is considered assuming that all data per
170 * respective event fit with in the limit.Please take a call
171 * on the limit based on the data requirements on link layer
172 * statistics.
173 */
174#define EXTTDLS_EVENT_BUF_SIZE 4096
175
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530176static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700177{
178 WLAN_CIPHER_SUITE_WEP40,
179 WLAN_CIPHER_SUITE_WEP104,
180 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800181#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700182#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
183 WLAN_CIPHER_SUITE_KRK,
184 WLAN_CIPHER_SUITE_CCMP,
185#else
186 WLAN_CIPHER_SUITE_CCMP,
187#endif
188#ifdef FEATURE_WLAN_WAPI
189 WLAN_CIPHER_SUITE_SMS4,
190#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700191#ifdef WLAN_FEATURE_11W
192 WLAN_CIPHER_SUITE_AES_CMAC,
193#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700194};
195
196static inline int is_broadcast_ether_addr(const u8 *addr)
197{
198 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
199 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
200}
201
202static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530203{
Jeff Johnson295189b2012-06-20 16:38:30 -0700204 HDD2GHZCHAN(2412, 1, 0) ,
205 HDD2GHZCHAN(2417, 2, 0) ,
206 HDD2GHZCHAN(2422, 3, 0) ,
207 HDD2GHZCHAN(2427, 4, 0) ,
208 HDD2GHZCHAN(2432, 5, 0) ,
209 HDD2GHZCHAN(2437, 6, 0) ,
210 HDD2GHZCHAN(2442, 7, 0) ,
211 HDD2GHZCHAN(2447, 8, 0) ,
212 HDD2GHZCHAN(2452, 9, 0) ,
213 HDD2GHZCHAN(2457, 10, 0) ,
214 HDD2GHZCHAN(2462, 11, 0) ,
215 HDD2GHZCHAN(2467, 12, 0) ,
216 HDD2GHZCHAN(2472, 13, 0) ,
217 HDD2GHZCHAN(2484, 14, 0) ,
218};
219
Jeff Johnson295189b2012-06-20 16:38:30 -0700220static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
221{
222 HDD2GHZCHAN(2412, 1, 0) ,
223 HDD2GHZCHAN(2437, 6, 0) ,
224 HDD2GHZCHAN(2462, 11, 0) ,
225};
Jeff Johnson295189b2012-06-20 16:38:30 -0700226
227static struct ieee80211_channel hdd_channels_5_GHZ[] =
228{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700229 HDD5GHZCHAN(4920, 240, 0) ,
230 HDD5GHZCHAN(4940, 244, 0) ,
231 HDD5GHZCHAN(4960, 248, 0) ,
232 HDD5GHZCHAN(4980, 252, 0) ,
233 HDD5GHZCHAN(5040, 208, 0) ,
234 HDD5GHZCHAN(5060, 212, 0) ,
235 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700236 HDD5GHZCHAN(5180, 36, 0) ,
237 HDD5GHZCHAN(5200, 40, 0) ,
238 HDD5GHZCHAN(5220, 44, 0) ,
239 HDD5GHZCHAN(5240, 48, 0) ,
240 HDD5GHZCHAN(5260, 52, 0) ,
241 HDD5GHZCHAN(5280, 56, 0) ,
242 HDD5GHZCHAN(5300, 60, 0) ,
243 HDD5GHZCHAN(5320, 64, 0) ,
244 HDD5GHZCHAN(5500,100, 0) ,
245 HDD5GHZCHAN(5520,104, 0) ,
246 HDD5GHZCHAN(5540,108, 0) ,
247 HDD5GHZCHAN(5560,112, 0) ,
248 HDD5GHZCHAN(5580,116, 0) ,
249 HDD5GHZCHAN(5600,120, 0) ,
250 HDD5GHZCHAN(5620,124, 0) ,
251 HDD5GHZCHAN(5640,128, 0) ,
252 HDD5GHZCHAN(5660,132, 0) ,
253 HDD5GHZCHAN(5680,136, 0) ,
254 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800255#ifdef FEATURE_WLAN_CH144
256 HDD5GHZCHAN(5720,144, 0) ,
257#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700258 HDD5GHZCHAN(5745,149, 0) ,
259 HDD5GHZCHAN(5765,153, 0) ,
260 HDD5GHZCHAN(5785,157, 0) ,
261 HDD5GHZCHAN(5805,161, 0) ,
262 HDD5GHZCHAN(5825,165, 0) ,
263};
264
265static struct ieee80211_rate g_mode_rates[] =
266{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530267 HDD_G_MODE_RATETAB(10, 0x1, 0),
268 HDD_G_MODE_RATETAB(20, 0x2, 0),
269 HDD_G_MODE_RATETAB(55, 0x4, 0),
270 HDD_G_MODE_RATETAB(110, 0x8, 0),
271 HDD_G_MODE_RATETAB(60, 0x10, 0),
272 HDD_G_MODE_RATETAB(90, 0x20, 0),
273 HDD_G_MODE_RATETAB(120, 0x40, 0),
274 HDD_G_MODE_RATETAB(180, 0x80, 0),
275 HDD_G_MODE_RATETAB(240, 0x100, 0),
276 HDD_G_MODE_RATETAB(360, 0x200, 0),
277 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700278 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530279};
Jeff Johnson295189b2012-06-20 16:38:30 -0700280
281static struct ieee80211_rate a_mode_rates[] =
282{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530283 HDD_G_MODE_RATETAB(60, 0x10, 0),
284 HDD_G_MODE_RATETAB(90, 0x20, 0),
285 HDD_G_MODE_RATETAB(120, 0x40, 0),
286 HDD_G_MODE_RATETAB(180, 0x80, 0),
287 HDD_G_MODE_RATETAB(240, 0x100, 0),
288 HDD_G_MODE_RATETAB(360, 0x200, 0),
289 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700290 HDD_G_MODE_RATETAB(540, 0x800, 0),
291};
292
293static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
294{
295 .channels = hdd_channels_2_4_GHZ,
296 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
297 .band = IEEE80211_BAND_2GHZ,
298 .bitrates = g_mode_rates,
299 .n_bitrates = g_mode_rates_size,
300 .ht_cap.ht_supported = 1,
301 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
302 | IEEE80211_HT_CAP_GRN_FLD
303 | IEEE80211_HT_CAP_DSSSCCK40
304 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
305 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
306 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
307 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
308 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
309 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
310};
311
Jeff Johnson295189b2012-06-20 16:38:30 -0700312static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
313{
314 .channels = hdd_social_channels_2_4_GHZ,
315 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
316 .band = IEEE80211_BAND_2GHZ,
317 .bitrates = g_mode_rates,
318 .n_bitrates = g_mode_rates_size,
319 .ht_cap.ht_supported = 1,
320 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
321 | IEEE80211_HT_CAP_GRN_FLD
322 | IEEE80211_HT_CAP_DSSSCCK40
323 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
324 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
325 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
326 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
327 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
328 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
329};
Jeff Johnson295189b2012-06-20 16:38:30 -0700330
331static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
332{
333 .channels = hdd_channels_5_GHZ,
334 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
335 .band = IEEE80211_BAND_5GHZ,
336 .bitrates = a_mode_rates,
337 .n_bitrates = a_mode_rates_size,
338 .ht_cap.ht_supported = 1,
339 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
340 | IEEE80211_HT_CAP_GRN_FLD
341 | IEEE80211_HT_CAP_DSSSCCK40
342 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
343 | IEEE80211_HT_CAP_SGI_40
344 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
345 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
346 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
347 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
348 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
349 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
350};
351
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530352/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700353 TX/RX direction for each kind of interface */
354static const struct ieee80211_txrx_stypes
355wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
356 [NL80211_IFTYPE_STATION] = {
357 .tx = 0xffff,
358 .rx = BIT(SIR_MAC_MGMT_ACTION) |
359 BIT(SIR_MAC_MGMT_PROBE_REQ),
360 },
361 [NL80211_IFTYPE_AP] = {
362 .tx = 0xffff,
363 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
364 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
365 BIT(SIR_MAC_MGMT_PROBE_REQ) |
366 BIT(SIR_MAC_MGMT_DISASSOC) |
367 BIT(SIR_MAC_MGMT_AUTH) |
368 BIT(SIR_MAC_MGMT_DEAUTH) |
369 BIT(SIR_MAC_MGMT_ACTION),
370 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700371 [NL80211_IFTYPE_ADHOC] = {
372 .tx = 0xffff,
373 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
374 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
375 BIT(SIR_MAC_MGMT_PROBE_REQ) |
376 BIT(SIR_MAC_MGMT_DISASSOC) |
377 BIT(SIR_MAC_MGMT_AUTH) |
378 BIT(SIR_MAC_MGMT_DEAUTH) |
379 BIT(SIR_MAC_MGMT_ACTION),
380 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700381 [NL80211_IFTYPE_P2P_CLIENT] = {
382 .tx = 0xffff,
383 .rx = BIT(SIR_MAC_MGMT_ACTION) |
384 BIT(SIR_MAC_MGMT_PROBE_REQ),
385 },
386 [NL80211_IFTYPE_P2P_GO] = {
387 /* This is also same as for SoftAP */
388 .tx = 0xffff,
389 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
390 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
391 BIT(SIR_MAC_MGMT_PROBE_REQ) |
392 BIT(SIR_MAC_MGMT_DISASSOC) |
393 BIT(SIR_MAC_MGMT_AUTH) |
394 BIT(SIR_MAC_MGMT_DEAUTH) |
395 BIT(SIR_MAC_MGMT_ACTION),
396 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700397};
398
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800399#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800400static const struct ieee80211_iface_limit
401wlan_hdd_iface_limit[] = {
402 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800403 /* max = 3 ; Our driver create two interfaces during driver init
404 * wlan0 and p2p0 interfaces. p2p0 is considered as station
405 * interface until a group is formed. In JB architecture, once the
406 * group is formed, interface type of p2p0 is changed to P2P GO or
407 * Client.
408 * When supplicant remove the group, it first issue a set interface
409 * cmd to change the mode back to Station. In JB this works fine as
410 * we advertize two station type interface during driver init.
411 * Some vendors create separate interface for P2P GO/Client,
412 * after group formation(Third one). But while group remove
413 * supplicant first tries to change the mode(3rd interface) to STATION
414 * But as we advertized only two sta type interfaces nl80211 was
415 * returning error for the third one which was leading to failure in
416 * delete interface. Ideally while removing the group, supplicant
417 * should not try to change the 3rd interface mode to Station type.
418 * Till we get a fix in wpa_supplicant, we advertize max STA
419 * interface type to 3
420 */
421 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800422 .types = BIT(NL80211_IFTYPE_STATION),
423 },
424 {
425 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700426 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800427 },
428 {
429 .max = 1,
430 .types = BIT(NL80211_IFTYPE_P2P_GO) |
431 BIT(NL80211_IFTYPE_P2P_CLIENT),
432 },
433};
434
435/* By default, only single channel concurrency is allowed */
436static struct ieee80211_iface_combination
437wlan_hdd_iface_combination = {
438 .limits = wlan_hdd_iface_limit,
439 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800440 /*
441 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
442 * and p2p0 interfaces during driver init
443 * Some vendors create separate interface for P2P operations.
444 * wlan0: STA interface
445 * p2p0: P2P Device interface, action frames goes
446 * through this interface.
447 * p2p-xx: P2P interface, After GO negotiation this interface is
448 * created for p2p operations(GO/CLIENT interface).
449 */
450 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800451 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
452 .beacon_int_infra_match = false,
453};
454#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800455
Jeff Johnson295189b2012-06-20 16:38:30 -0700456static struct cfg80211_ops wlan_hdd_cfg80211_ops;
457
458/* Data rate 100KBPS based on IE Index */
459struct index_data_rate_type
460{
461 v_U8_t beacon_rate_index;
462 v_U16_t supported_rate[4];
463};
464
465/* 11B, 11G Rate table include Basic rate and Extended rate
466 The IDX field is the rate index
467 The HI field is the rate when RSSI is strong or being ignored
468 (in this case we report actual rate)
469 The MID field is the rate when RSSI is moderate
470 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
471 The LO field is the rate when RSSI is low
472 (in this case we don't report rates, actual current rate used)
473 */
474static const struct
475{
476 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700477 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700478} supported_data_rate[] =
479{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700480/* IDX HI HM LM LO (RSSI-based index */
481 {2, { 10, 10, 10, 0}},
482 {4, { 20, 20, 10, 0}},
483 {11, { 55, 20, 10, 0}},
484 {12, { 60, 55, 20, 0}},
485 {18, { 90, 55, 20, 0}},
486 {22, {110, 55, 20, 0}},
487 {24, {120, 90, 60, 0}},
488 {36, {180, 120, 60, 0}},
489 {44, {220, 180, 60, 0}},
490 {48, {240, 180, 90, 0}},
491 {66, {330, 180, 90, 0}},
492 {72, {360, 240, 90, 0}},
493 {96, {480, 240, 120, 0}},
494 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700495};
496
497/* MCS Based rate table */
498static struct index_data_rate_type supported_mcs_rate[] =
499{
500/* MCS L20 L40 S20 S40 */
501 {0, {65, 135, 72, 150}},
502 {1, {130, 270, 144, 300}},
503 {2, {195, 405, 217, 450}},
504 {3, {260, 540, 289, 600}},
505 {4, {390, 810, 433, 900}},
506 {5, {520, 1080, 578, 1200}},
507 {6, {585, 1215, 650, 1350}},
508 {7, {650, 1350, 722, 1500}}
509};
510
Leo Chang6f8870f2013-03-26 18:11:36 -0700511#ifdef WLAN_FEATURE_11AC
512
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530513#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700514
515struct index_vht_data_rate_type
516{
517 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530518 v_U16_t supported_VHT80_rate[2];
519 v_U16_t supported_VHT40_rate[2];
520 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700521};
522
523typedef enum
524{
525 DATA_RATE_11AC_MAX_MCS_7,
526 DATA_RATE_11AC_MAX_MCS_8,
527 DATA_RATE_11AC_MAX_MCS_9,
528 DATA_RATE_11AC_MAX_MCS_NA
529} eDataRate11ACMaxMcs;
530
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530531/* SSID broadcast type */
532typedef enum eSSIDBcastType
533{
534 eBCAST_UNKNOWN = 0,
535 eBCAST_NORMAL = 1,
536 eBCAST_HIDDEN = 2,
537} tSSIDBcastType;
538
Leo Chang6f8870f2013-03-26 18:11:36 -0700539/* MCS Based VHT rate table */
540static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
541{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530542/* MCS L80 S80 L40 S40 L20 S40*/
543 {0, {293, 325}, {135, 150}, {65, 72}},
544 {1, {585, 650}, {270, 300}, {130, 144}},
545 {2, {878, 975}, {405, 450}, {195, 217}},
546 {3, {1170, 1300}, {540, 600}, {260, 289}},
547 {4, {1755, 1950}, {810, 900}, {390, 433}},
548 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
549 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
550 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
551 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
552 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700553};
554#endif /* WLAN_FEATURE_11AC */
555
c_hpothu79aab322014-07-14 21:11:01 +0530556/*array index points to MCS and array value points respective rssi*/
557static int rssiMcsTbl[][10] =
558{
559/*MCS 0 1 2 3 4 5 6 7 8 9*/
560 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
561 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
562 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
563};
564
Jeff Johnson295189b2012-06-20 16:38:30 -0700565extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530566#ifdef FEATURE_WLAN_SCAN_PNO
567static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
568#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700569
Leo Chang9056f462013-08-01 19:21:11 -0700570#ifdef WLAN_NL80211_TESTMODE
571enum wlan_hdd_tm_attr
572{
573 WLAN_HDD_TM_ATTR_INVALID = 0,
574 WLAN_HDD_TM_ATTR_CMD = 1,
575 WLAN_HDD_TM_ATTR_DATA = 2,
576 WLAN_HDD_TM_ATTR_TYPE = 3,
577 /* keep last */
578 WLAN_HDD_TM_ATTR_AFTER_LAST,
579 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
580};
581
582enum wlan_hdd_tm_cmd
583{
584 WLAN_HDD_TM_CMD_WLAN_HB = 1,
585};
586
587#define WLAN_HDD_TM_DATA_MAX_LEN 5000
588
589static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
590{
591 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
592 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
593 .len = WLAN_HDD_TM_DATA_MAX_LEN },
594};
595#endif /* WLAN_NL80211_TESTMODE */
596
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800597#ifdef FEATURE_WLAN_CH_AVOID
598/*
599 * FUNCTION: wlan_hdd_send_avoid_freq_event
600 * This is called when wlan driver needs to send vendor specific
601 * avoid frequency range event to userspace
602 */
603int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
604 tHddAvoidFreqList *pAvoidFreqList)
605{
606 struct sk_buff *vendor_event;
607
608 ENTER();
609
610 if (!pHddCtx)
611 {
612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
613 "%s: HDD context is null", __func__);
614 return -1;
615 }
616
617 if (!pAvoidFreqList)
618 {
619 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
620 "%s: pAvoidFreqList is null", __func__);
621 return -1;
622 }
623
624 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530625#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
626 NULL,
627#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800628 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530629 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800630 GFP_KERNEL);
631 if (!vendor_event)
632 {
633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
634 "%s: cfg80211_vendor_event_alloc failed", __func__);
635 return -1;
636 }
637
638 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
639 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
640
641 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
642
643 EXIT();
644 return 0;
645}
646#endif /* FEATURE_WLAN_CH_AVOID */
647
Srinivas Dasari030bad32015-02-18 23:23:54 +0530648/*
649 * FUNCTION: __wlan_hdd_cfg80211_nan_request
650 * This is called when wlan driver needs to send vendor specific
651 * nan request event.
652 */
653static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
654 struct wireless_dev *wdev,
655 const void *data, int data_len)
656{
657 tNanRequestReq nan_req;
658 VOS_STATUS status;
659 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530660 struct net_device *dev = wdev->netdev;
661 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
662 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530663 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
664
665 if (0 == data_len)
666 {
667 hddLog(VOS_TRACE_LEVEL_ERROR,
668 FL("NAN - Invalid Request, length = 0"));
669 return ret_val;
670 }
671
672 if (NULL == data)
673 {
674 hddLog(VOS_TRACE_LEVEL_ERROR,
675 FL("NAN - Invalid Request, data is NULL"));
676 return ret_val;
677 }
678
679 status = wlan_hdd_validate_context(pHddCtx);
680 if (0 != status)
681 {
682 hddLog(VOS_TRACE_LEVEL_ERROR,
683 FL("HDD context is not valid"));
684 return -EINVAL;
685 }
686
687 hddLog(LOG1, FL("Received NAN command"));
688 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
689 (tANI_U8 *)data, data_len);
690
691 /* check the NAN Capability */
692 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
693 {
694 hddLog(VOS_TRACE_LEVEL_ERROR,
695 FL("NAN is not supported by Firmware"));
696 return -EINVAL;
697 }
698
699 nan_req.request_data_len = data_len;
700 nan_req.request_data = data;
701
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530702 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530703 if (VOS_STATUS_SUCCESS == status)
704 {
705 ret_val = 0;
706 }
707 return ret_val;
708}
709
710/*
711 * FUNCTION: wlan_hdd_cfg80211_nan_request
712 * Wrapper to protect the nan vendor command from ssr
713 */
714static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
715 struct wireless_dev *wdev,
716 const void *data, int data_len)
717{
718 int ret;
719
720 vos_ssr_protect(__func__);
721 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
722 vos_ssr_unprotect(__func__);
723
724 return ret;
725}
726
727/*
728 * FUNCTION: wlan_hdd_cfg80211_nan_callback
729 * This is a callback function and it gets called
730 * when we need to report nan response event to
731 * upper layers.
732 */
733static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
734{
735 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
736 struct sk_buff *vendor_event;
737 int status;
738 tSirNanEvent *data;
739
740 ENTER();
741 if (NULL == msg)
742 {
743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
744 FL(" msg received here is null"));
745 return;
746 }
747 data = msg;
748
749 status = wlan_hdd_validate_context(pHddCtx);
750
751 if (0 != status)
752 {
753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
754 FL("HDD context is not valid"));
755 return;
756 }
757
758 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530759#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
760 NULL,
761#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530762 data->event_data_len +
763 NLMSG_HDRLEN,
764 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
765 GFP_KERNEL);
766
767 if (!vendor_event)
768 {
769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
770 FL("cfg80211_vendor_event_alloc failed"));
771 return;
772 }
773 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
774 data->event_data_len, data->event_data))
775 {
776 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
777 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
778 kfree_skb(vendor_event);
779 return;
780 }
781 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
782 EXIT();
783}
784
785/*
786 * FUNCTION: wlan_hdd_cfg80211_nan_init
787 * This function is called to register the callback to sme layer
788 */
789inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
790{
791 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
792}
793
794
Sunil Duttc69bccb2014-05-26 21:30:20 +0530795#ifdef WLAN_FEATURE_LINK_LAYER_STATS
796
797static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
798 struct sk_buff *vendor_event)
799{
800 if (nla_put_u8(vendor_event,
801 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
802 stats->rate.preamble) ||
803 nla_put_u8(vendor_event,
804 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
805 stats->rate.nss) ||
806 nla_put_u8(vendor_event,
807 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
808 stats->rate.bw) ||
809 nla_put_u8(vendor_event,
810 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
811 stats->rate.rateMcsIdx) ||
812 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
813 stats->rate.bitrate ) ||
814 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
815 stats->txMpdu ) ||
816 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
817 stats->rxMpdu ) ||
818 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
819 stats->mpduLost ) ||
820 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
821 stats->retries) ||
822 nla_put_u32(vendor_event,
823 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
824 stats->retriesShort ) ||
825 nla_put_u32(vendor_event,
826 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
827 stats->retriesLong))
828 {
829 hddLog(VOS_TRACE_LEVEL_ERROR,
830 FL("QCA_WLAN_VENDOR_ATTR put fail"));
831 return FALSE;
832 }
833 return TRUE;
834}
835
836static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
837 struct sk_buff *vendor_event)
838{
839 u32 i = 0;
840 struct nlattr *rateInfo;
841 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
842 stats->type) ||
843 nla_put(vendor_event,
844 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
845 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
846 nla_put_u32(vendor_event,
847 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
848 stats->capabilities) ||
849 nla_put_u32(vendor_event,
850 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
851 stats->numRate))
852 {
853 hddLog(VOS_TRACE_LEVEL_ERROR,
854 FL("QCA_WLAN_VENDOR_ATTR put fail"));
855 goto error;
856 }
857
858 rateInfo = nla_nest_start(vendor_event,
859 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530860 if(!rateInfo)
861 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530862 for (i = 0; i < stats->numRate; i++)
863 {
864 struct nlattr *rates;
865 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
866 stats->rateStats +
867 (i * sizeof(tSirWifiRateStat)));
868 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530869 if(!rates)
870 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530871
872 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
873 {
874 hddLog(VOS_TRACE_LEVEL_ERROR,
875 FL("QCA_WLAN_VENDOR_ATTR put fail"));
876 return FALSE;
877 }
878 nla_nest_end(vendor_event, rates);
879 }
880 nla_nest_end(vendor_event, rateInfo);
881
882 return TRUE;
883error:
884 return FALSE;
885}
886
887static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
888 struct sk_buff *vendor_event)
889{
890 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
891 stats->ac ) ||
892 nla_put_u32(vendor_event,
893 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
894 stats->txMpdu ) ||
895 nla_put_u32(vendor_event,
896 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
897 stats->rxMpdu ) ||
898 nla_put_u32(vendor_event,
899 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
900 stats->txMcast ) ||
901 nla_put_u32(vendor_event,
902 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
903 stats->rxMcast ) ||
904 nla_put_u32(vendor_event,
905 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
906 stats->rxAmpdu ) ||
907 nla_put_u32(vendor_event,
908 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
909 stats->txAmpdu ) ||
910 nla_put_u32(vendor_event,
911 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
912 stats->mpduLost )||
913 nla_put_u32(vendor_event,
914 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
915 stats->retries ) ||
916 nla_put_u32(vendor_event,
917 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
918 stats->retriesShort ) ||
919 nla_put_u32(vendor_event,
920 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
921 stats->retriesLong ) ||
922 nla_put_u32(vendor_event,
923 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
924 stats->contentionTimeMin ) ||
925 nla_put_u32(vendor_event,
926 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
927 stats->contentionTimeMax ) ||
928 nla_put_u32(vendor_event,
929 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
930 stats->contentionTimeAvg ) ||
931 nla_put_u32(vendor_event,
932 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
933 stats->contentionNumSamples ))
934 {
935 hddLog(VOS_TRACE_LEVEL_ERROR,
936 FL("QCA_WLAN_VENDOR_ATTR put fail") );
937 return FALSE;
938 }
939 return TRUE;
940}
941
942static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
943 struct sk_buff *vendor_event)
944{
Dino Myclec8f3f332014-07-21 16:48:27 +0530945 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530946 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
947 nla_put(vendor_event,
948 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
949 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
950 nla_put_u32(vendor_event,
951 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
952 stats->state ) ||
953 nla_put_u32(vendor_event,
954 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
955 stats->roaming ) ||
956 nla_put_u32(vendor_event,
957 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
958 stats->capabilities ) ||
959 nla_put(vendor_event,
960 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
961 strlen(stats->ssid), stats->ssid) ||
962 nla_put(vendor_event,
963 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
964 WNI_CFG_BSSID_LEN, stats->bssid) ||
965 nla_put(vendor_event,
966 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
967 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
968 nla_put(vendor_event,
969 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
970 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
971 )
972 {
973 hddLog(VOS_TRACE_LEVEL_ERROR,
974 FL("QCA_WLAN_VENDOR_ATTR put fail") );
975 return FALSE;
976 }
977 return TRUE;
978}
979
Dino Mycle3b9536d2014-07-09 22:05:24 +0530980static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
981 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530982 struct sk_buff *vendor_event)
983{
984 int i = 0;
985 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530986 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
987 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530988 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530989
Sunil Duttc69bccb2014-05-26 21:30:20 +0530990 if (FALSE == put_wifi_interface_info(
991 &pWifiIfaceStat->info,
992 vendor_event))
993 {
994 hddLog(VOS_TRACE_LEVEL_ERROR,
995 FL("QCA_WLAN_VENDOR_ATTR put fail") );
996 return FALSE;
997
998 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530999 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
1000 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
1001 if (NULL == pWifiIfaceStatTL)
1002 {
1003 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
1004 return FALSE;
1005 }
1006
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301007 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
1008 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1009 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1010 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1011
1012 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1013 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1014 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1015 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301016
1017 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1018 {
1019 if (VOS_STATUS_SUCCESS ==
1020 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1021 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1022 {
1023 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1024 * obtained from TL structure
1025 */
1026
1027 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1028 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301029 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1030
Srinivas Dasari98947432014-11-07 19:41:24 +05301031 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1032 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1033 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1034 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1035 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1036 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1037 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1038 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301039
Srinivas Dasari98947432014-11-07 19:41:24 +05301040 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1041 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1042 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1043 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1044 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1045 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1046 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1047 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301048
Srinivas Dasari98947432014-11-07 19:41:24 +05301049 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1050 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1051 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1052 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1053 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1054 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1055 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1056 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301057 }
1058 else
1059 {
1060 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1061 }
1062
Dino Mycle3b9536d2014-07-09 22:05:24 +05301063 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1064 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1065 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1066 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1067 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1068 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1069 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1070 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1071 }
1072 else
1073 {
1074 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1075 }
1076
1077
Sunil Duttc69bccb2014-05-26 21:30:20 +05301078
1079 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301080 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1081 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1082 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301083 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1084 pWifiIfaceStat->beaconRx) ||
1085 nla_put_u32(vendor_event,
1086 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1087 pWifiIfaceStat->mgmtRx) ||
1088 nla_put_u32(vendor_event,
1089 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1090 pWifiIfaceStat->mgmtActionRx) ||
1091 nla_put_u32(vendor_event,
1092 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1093 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301094 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301095 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1096 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301097 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301098 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1099 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301100 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301101 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1102 pWifiIfaceStat->rssiAck))
1103 {
1104 hddLog(VOS_TRACE_LEVEL_ERROR,
1105 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301106 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301107 return FALSE;
1108 }
1109
1110 wmmInfo = nla_nest_start(vendor_event,
1111 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301112 if(!wmmInfo)
1113 {
1114 vos_mem_free(pWifiIfaceStatTL);
1115 return FALSE;
1116 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301117 for (i = 0; i < WIFI_AC_MAX; i++)
1118 {
1119 struct nlattr *wmmStats;
1120 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301121 if(!wmmStats)
1122 {
1123 vos_mem_free(pWifiIfaceStatTL);
1124 return FALSE;
1125 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301126 if (FALSE == put_wifi_wmm_ac_stat(
1127 &pWifiIfaceStat->AccessclassStats[i],
1128 vendor_event))
1129 {
1130 hddLog(VOS_TRACE_LEVEL_ERROR,
1131 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301132 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301133 return FALSE;
1134 }
1135
1136 nla_nest_end(vendor_event, wmmStats);
1137 }
1138 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301139 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301140 return TRUE;
1141}
1142
1143static tSirWifiInterfaceMode
1144 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1145{
1146 switch (deviceMode)
1147 {
1148 case WLAN_HDD_INFRA_STATION:
1149 return WIFI_INTERFACE_STA;
1150 case WLAN_HDD_SOFTAP:
1151 return WIFI_INTERFACE_SOFTAP;
1152 case WLAN_HDD_P2P_CLIENT:
1153 return WIFI_INTERFACE_P2P_CLIENT;
1154 case WLAN_HDD_P2P_GO:
1155 return WIFI_INTERFACE_P2P_GO;
1156 case WLAN_HDD_IBSS:
1157 return WIFI_INTERFACE_IBSS;
1158 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301159 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301160 }
1161}
1162
1163static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1164 tpSirWifiInterfaceInfo pInfo)
1165{
1166 v_U8_t *staMac = NULL;
1167 hdd_station_ctx_t *pHddStaCtx;
1168 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1169 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1170
1171 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1172
1173 vos_mem_copy(pInfo->macAddr,
1174 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1175
1176 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1177 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1178 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1179 {
1180 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1181 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1182 {
1183 pInfo->state = WIFI_DISCONNECTED;
1184 }
1185 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1186 {
1187 hddLog(VOS_TRACE_LEVEL_ERROR,
1188 "%s: Session ID %d, Connection is in progress", __func__,
1189 pAdapter->sessionId);
1190 pInfo->state = WIFI_ASSOCIATING;
1191 }
1192 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1193 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1194 {
1195 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1196 hddLog(VOS_TRACE_LEVEL_ERROR,
1197 "%s: client " MAC_ADDRESS_STR
1198 " is in the middle of WPS/EAPOL exchange.", __func__,
1199 MAC_ADDR_ARRAY(staMac));
1200 pInfo->state = WIFI_AUTHENTICATING;
1201 }
1202 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1203 {
1204 pInfo->state = WIFI_ASSOCIATED;
1205 vos_mem_copy(pInfo->bssid,
1206 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1207 vos_mem_copy(pInfo->ssid,
1208 pHddStaCtx->conn_info.SSID.SSID.ssId,
1209 pHddStaCtx->conn_info.SSID.SSID.length);
1210 //NULL Terminate the string.
1211 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1212 }
1213 }
1214 vos_mem_copy(pInfo->countryStr,
1215 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1216
1217 vos_mem_copy(pInfo->apCountryStr,
1218 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1219
1220 return TRUE;
1221}
1222
1223/*
1224 * hdd_link_layer_process_peer_stats () - This function is called after
1225 * receiving Link Layer Peer statistics from FW.This function converts
1226 * the firmware data to the NL data and sends the same to the kernel/upper
1227 * layers.
1228 */
1229static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1230 v_VOID_t *pData)
1231{
1232 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301233 tpSirWifiPeerStat pWifiPeerStat;
1234 tpSirWifiPeerInfo pWifiPeerInfo;
1235 struct nlattr *peerInfo;
1236 struct sk_buff *vendor_event;
1237 int status, i;
1238
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301239 ENTER();
1240
Sunil Duttc69bccb2014-05-26 21:30:20 +05301241 status = wlan_hdd_validate_context(pHddCtx);
1242 if (0 != status)
1243 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301244 return;
1245 }
1246
1247 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1248
1249 hddLog(VOS_TRACE_LEVEL_INFO,
1250 "LL_STATS_PEER_ALL : numPeers %u",
1251 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301252 /*
1253 * Allocate a size of 4096 for the peer stats comprising
1254 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1255 * sizeof (tSirWifiRateStat).Each field is put with an
1256 * NL attribute.The size of 4096 is considered assuming
1257 * that number of rates shall not exceed beyond 50 with
1258 * the sizeof (tSirWifiRateStat) being 32.
1259 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301260 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1261 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301262 if (!vendor_event)
1263 {
1264 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301265 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301266 __func__);
1267 return;
1268 }
1269 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301270 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1271 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1272 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301273 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1274 pWifiPeerStat->numPeers))
1275 {
1276 hddLog(VOS_TRACE_LEVEL_ERROR,
1277 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1278 kfree_skb(vendor_event);
1279 return;
1280 }
1281
1282 peerInfo = nla_nest_start(vendor_event,
1283 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301284 if(!peerInfo)
1285 {
1286 hddLog(VOS_TRACE_LEVEL_ERROR,
1287 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1288 __func__);
1289 kfree_skb(vendor_event);
1290 return;
1291 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301292
1293 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1294 pWifiPeerStat->peerInfo);
1295
1296 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1297 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301298 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301299 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301300
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301301 if(!peers)
1302 {
1303 hddLog(VOS_TRACE_LEVEL_ERROR,
1304 "%s: peer stats put fail",
1305 __func__);
1306 kfree_skb(vendor_event);
1307 return;
1308 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301309 if (FALSE == put_wifi_peer_info(
1310 pWifiPeerInfo, vendor_event))
1311 {
1312 hddLog(VOS_TRACE_LEVEL_ERROR,
1313 "%s: put_wifi_peer_info put fail", __func__);
1314 kfree_skb(vendor_event);
1315 return;
1316 }
1317
1318 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1319 pWifiPeerStat->peerInfo +
1320 (i * sizeof(tSirWifiPeerInfo)) +
1321 (numRate * sizeof (tSirWifiRateStat)));
1322 nla_nest_end(vendor_event, peers);
1323 }
1324 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301325 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301326 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301327}
1328
1329/*
1330 * hdd_link_layer_process_iface_stats () - This function is called after
1331 * receiving Link Layer Interface statistics from FW.This function converts
1332 * the firmware data to the NL data and sends the same to the kernel/upper
1333 * layers.
1334 */
1335static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1336 v_VOID_t *pData)
1337{
1338 tpSirWifiIfaceStat pWifiIfaceStat;
1339 struct sk_buff *vendor_event;
1340 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1341 int status;
1342
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301343 ENTER();
1344
Sunil Duttc69bccb2014-05-26 21:30:20 +05301345 status = wlan_hdd_validate_context(pHddCtx);
1346 if (0 != status)
1347 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301348 return;
1349 }
1350 /*
1351 * Allocate a size of 4096 for the interface stats comprising
1352 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1353 * assuming that all these fit with in the limit.Please take
1354 * a call on the limit based on the data requirements on
1355 * interface statistics.
1356 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301357 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1358 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301359 if (!vendor_event)
1360 {
1361 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301362 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301363 return;
1364 }
1365
1366 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1367
Dino Mycle3b9536d2014-07-09 22:05:24 +05301368
1369 if (FALSE == hdd_get_interface_info( pAdapter,
1370 &pWifiIfaceStat->info))
1371 {
1372 hddLog(VOS_TRACE_LEVEL_ERROR,
1373 FL("hdd_get_interface_info get fail") );
1374 kfree_skb(vendor_event);
1375 return;
1376 }
1377
1378 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1379 vendor_event))
1380 {
1381 hddLog(VOS_TRACE_LEVEL_ERROR,
1382 FL("put_wifi_iface_stats fail") );
1383 kfree_skb(vendor_event);
1384 return;
1385 }
1386
Sunil Duttc69bccb2014-05-26 21:30:20 +05301387 hddLog(VOS_TRACE_LEVEL_INFO,
1388 "WMI_LINK_STATS_IFACE Data");
1389
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301390 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301391
1392 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301393}
1394
1395/*
1396 * hdd_link_layer_process_radio_stats () - This function is called after
1397 * receiving Link Layer Radio statistics from FW.This function converts
1398 * the firmware data to the NL data and sends the same to the kernel/upper
1399 * layers.
1400 */
1401static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1402 v_VOID_t *pData)
1403{
1404 int status, i;
1405 tpSirWifiRadioStat pWifiRadioStat;
1406 tpSirWifiChannelStats pWifiChannelStats;
1407 struct sk_buff *vendor_event;
1408 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1409 struct nlattr *chList;
1410
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301411 ENTER();
1412
Sunil Duttc69bccb2014-05-26 21:30:20 +05301413 status = wlan_hdd_validate_context(pHddCtx);
1414 if (0 != status)
1415 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301416 return;
1417 }
1418 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1419
1420 hddLog(VOS_TRACE_LEVEL_INFO,
1421 "LL_STATS_RADIO"
1422 " radio is %d onTime is %u "
1423 " txTime is %u rxTime is %u "
1424 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301425 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301426 " onTimePnoScan is %u onTimeHs20 is %u "
1427 " numChannels is %u",
1428 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1429 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1430 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301431 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301432 pWifiRadioStat->onTimeRoamScan,
1433 pWifiRadioStat->onTimePnoScan,
1434 pWifiRadioStat->onTimeHs20,
1435 pWifiRadioStat->numChannels);
1436 /*
1437 * Allocate a size of 4096 for the Radio stats comprising
1438 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1439 * (tSirWifiChannelStats).Each channel data is put with an
1440 * NL attribute.The size of 4096 is considered assuming that
1441 * number of channels shall not exceed beyond 60 with the
1442 * sizeof (tSirWifiChannelStats) being 24 bytes.
1443 */
1444
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301445 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1446 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301447 if (!vendor_event)
1448 {
1449 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301450 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301451 return;
1452 }
1453
1454 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301455 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1456 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1457 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301458 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1459 pWifiRadioStat->radio) ||
1460 nla_put_u32(vendor_event,
1461 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1462 pWifiRadioStat->onTime) ||
1463 nla_put_u32(vendor_event,
1464 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1465 pWifiRadioStat->txTime) ||
1466 nla_put_u32(vendor_event,
1467 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1468 pWifiRadioStat->rxTime) ||
1469 nla_put_u32(vendor_event,
1470 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1471 pWifiRadioStat->onTimeScan) ||
1472 nla_put_u32(vendor_event,
1473 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1474 pWifiRadioStat->onTimeNbd) ||
1475 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301476 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1477 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301478 nla_put_u32(vendor_event,
1479 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1480 pWifiRadioStat->onTimeRoamScan) ||
1481 nla_put_u32(vendor_event,
1482 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1483 pWifiRadioStat->onTimePnoScan) ||
1484 nla_put_u32(vendor_event,
1485 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1486 pWifiRadioStat->onTimeHs20) ||
1487 nla_put_u32(vendor_event,
1488 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1489 pWifiRadioStat->numChannels))
1490 {
1491 hddLog(VOS_TRACE_LEVEL_ERROR,
1492 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1493 kfree_skb(vendor_event);
1494 return ;
1495 }
1496
1497 chList = nla_nest_start(vendor_event,
1498 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301499 if(!chList)
1500 {
1501 hddLog(VOS_TRACE_LEVEL_ERROR,
1502 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1503 __func__);
1504 kfree_skb(vendor_event);
1505 return;
1506 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301507 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1508 {
1509 struct nlattr *chInfo;
1510
1511 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1512 pWifiRadioStat->channels +
1513 (i * sizeof(tSirWifiChannelStats)));
1514
Sunil Duttc69bccb2014-05-26 21:30:20 +05301515 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301516 if(!chInfo)
1517 {
1518 hddLog(VOS_TRACE_LEVEL_ERROR,
1519 "%s: failed to put chInfo",
1520 __func__);
1521 kfree_skb(vendor_event);
1522 return;
1523 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301524
1525 if (nla_put_u32(vendor_event,
1526 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1527 pWifiChannelStats->channel.width) ||
1528 nla_put_u32(vendor_event,
1529 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1530 pWifiChannelStats->channel.centerFreq) ||
1531 nla_put_u32(vendor_event,
1532 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1533 pWifiChannelStats->channel.centerFreq0) ||
1534 nla_put_u32(vendor_event,
1535 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1536 pWifiChannelStats->channel.centerFreq1) ||
1537 nla_put_u32(vendor_event,
1538 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1539 pWifiChannelStats->onTime) ||
1540 nla_put_u32(vendor_event,
1541 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1542 pWifiChannelStats->ccaBusyTime))
1543 {
1544 hddLog(VOS_TRACE_LEVEL_ERROR,
1545 FL("cfg80211_vendor_event_alloc failed") );
1546 kfree_skb(vendor_event);
1547 return ;
1548 }
1549 nla_nest_end(vendor_event, chInfo);
1550 }
1551 nla_nest_end(vendor_event, chList);
1552
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301553 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301554
1555 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301556 return;
1557}
1558
1559/*
1560 * hdd_link_layer_stats_ind_callback () - This function is called after
1561 * receiving Link Layer indications from FW.This callback converts the firmware
1562 * data to the NL data and send the same to the kernel/upper layers.
1563 */
1564static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1565 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301566 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301567{
Dino Mycled3d50022014-07-07 12:58:25 +05301568 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1569 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301570 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301571 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301572 int status;
1573
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301574 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301575
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301576 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301577 if (0 != status)
1578 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301579 return;
1580 }
1581
Dino Mycled3d50022014-07-07 12:58:25 +05301582 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1583 if (NULL == pAdapter)
1584 {
1585 hddLog(VOS_TRACE_LEVEL_ERROR,
1586 FL(" MAC address %pM does not exist with host"),
1587 macAddr);
1588 return;
1589 }
1590
Sunil Duttc69bccb2014-05-26 21:30:20 +05301591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301592 "%s: Interface: %s LLStats indType: %d", __func__,
1593 pAdapter->dev->name, indType);
1594
Sunil Duttc69bccb2014-05-26 21:30:20 +05301595 switch (indType)
1596 {
1597 case SIR_HAL_LL_STATS_RESULTS_RSP:
1598 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301599 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301600 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
1601 "respId = %u, moreResultToFollow = %u",
1602 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
1603 macAddr, linkLayerStatsResults->respId,
1604 linkLayerStatsResults->moreResultToFollow);
1605
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301606 spin_lock(&hdd_context_lock);
1607 context = &pHddCtx->ll_stats_context;
1608 /* validate response received from target */
1609 if ((context->request_id != linkLayerStatsResults->respId) ||
1610 !(context->request_bitmap & linkLayerStatsResults->paramId))
1611 {
1612 spin_unlock(&hdd_context_lock);
1613 hddLog(LOGE,
1614 FL("Error : Request id %d response id %d request bitmap 0x%x"
1615 "response bitmap 0x%x"),
1616 context->request_id, linkLayerStatsResults->respId,
1617 context->request_bitmap, linkLayerStatsResults->paramId);
1618 return;
1619 }
1620 spin_unlock(&hdd_context_lock);
1621
Sunil Duttc69bccb2014-05-26 21:30:20 +05301622 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1623 {
1624 hdd_link_layer_process_radio_stats(pAdapter,
1625 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301626 spin_lock(&hdd_context_lock);
1627 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1628 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301629 }
1630 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1631 {
1632 hdd_link_layer_process_iface_stats(pAdapter,
1633 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301634 spin_lock(&hdd_context_lock);
1635 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1636 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301637 }
1638 else if ( linkLayerStatsResults->paramId &
1639 WMI_LINK_STATS_ALL_PEER )
1640 {
1641 hdd_link_layer_process_peer_stats(pAdapter,
1642 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301643 spin_lock(&hdd_context_lock);
1644 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1645 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301646 } /* WMI_LINK_STATS_ALL_PEER */
1647 else
1648 {
1649 hddLog(VOS_TRACE_LEVEL_ERROR,
1650 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1651 }
1652
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301653 spin_lock(&hdd_context_lock);
1654 /* complete response event if all requests are completed */
1655 if (0 == context->request_bitmap)
1656 complete(&context->response_event);
1657 spin_unlock(&hdd_context_lock);
1658
Sunil Duttc69bccb2014-05-26 21:30:20 +05301659 break;
1660 }
1661 default:
1662 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1663 break;
1664 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301665
1666 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301667 return;
1668}
1669
1670const struct
1671nla_policy
1672qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1673{
1674 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1675 { .type = NLA_U32 },
1676 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1677 { .type = NLA_U32 },
1678};
1679
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301680static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1681 struct wireless_dev *wdev,
1682 const void *data,
1683 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301684{
1685 int status;
1686 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301687 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301688 struct net_device *dev = wdev->netdev;
1689 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1690 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1691
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301692 ENTER();
1693
Sunil Duttc69bccb2014-05-26 21:30:20 +05301694 status = wlan_hdd_validate_context(pHddCtx);
1695 if (0 != status)
1696 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301697 return -EINVAL;
1698 }
1699
1700 if (NULL == pAdapter)
1701 {
1702 hddLog(VOS_TRACE_LEVEL_ERROR,
1703 FL("HDD adapter is Null"));
1704 return -ENODEV;
1705 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301706 /* check the LLStats Capability */
1707 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1708 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1709 {
1710 hddLog(VOS_TRACE_LEVEL_ERROR,
1711 FL("Link Layer Statistics not supported by Firmware"));
1712 return -EINVAL;
1713 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301714
1715 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1716 (struct nlattr *)data,
1717 data_len, qca_wlan_vendor_ll_set_policy))
1718 {
1719 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1720 return -EINVAL;
1721 }
1722 if (!tb_vendor
1723 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1724 {
1725 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1726 return -EINVAL;
1727 }
1728 if (!tb_vendor[
1729 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1730 {
1731 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1732 return -EINVAL;
1733 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301734 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301735 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301736
Dino Mycledf0a5d92014-07-04 09:41:55 +05301737 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301738 nla_get_u32(
1739 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1740
Dino Mycledf0a5d92014-07-04 09:41:55 +05301741 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301742 nla_get_u32(
1743 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1744
Dino Mycled3d50022014-07-07 12:58:25 +05301745 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1746 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301747
1748
1749 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301750 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
1751 "Statistics Gathering = %d ",
1752 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
1753 linkLayerStatsSetReq.mpduSizeThreshold,
1754 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301755
1756 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1757 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301758 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301759 {
1760 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1761 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301762 return -EINVAL;
1763
1764 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301765
Sunil Duttc69bccb2014-05-26 21:30:20 +05301766 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301767 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301768 {
1769 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1770 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301771 return -EINVAL;
1772 }
1773
1774 pAdapter->isLinkLayerStatsSet = 1;
1775
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301776 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301777 return 0;
1778}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301779static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1780 struct wireless_dev *wdev,
1781 const void *data,
1782 int data_len)
1783{
1784 int ret = 0;
1785
1786 vos_ssr_protect(__func__);
1787 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1788 vos_ssr_unprotect(__func__);
1789
1790 return ret;
1791}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301792
1793const struct
1794nla_policy
1795qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1796{
1797 /* Unsigned 32bit value provided by the caller issuing the GET stats
1798 * command. When reporting
1799 * the stats results, the driver uses the same value to indicate
1800 * which GET request the results
1801 * correspond to.
1802 */
1803 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1804
1805 /* Unsigned 32bit value . bit mask to identify what statistics are
1806 requested for retrieval */
1807 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1808};
1809
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301810static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1811 struct wireless_dev *wdev,
1812 const void *data,
1813 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301814{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301815 unsigned long rc;
1816 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301817 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1818 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301819 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301820 struct net_device *dev = wdev->netdev;
1821 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301822 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301823 int status;
1824
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301825 ENTER();
1826
Sunil Duttc69bccb2014-05-26 21:30:20 +05301827 status = wlan_hdd_validate_context(pHddCtx);
1828 if (0 != status)
1829 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301830 return -EINVAL ;
1831 }
1832
1833 if (NULL == pAdapter)
1834 {
1835 hddLog(VOS_TRACE_LEVEL_FATAL,
1836 "%s: HDD adapter is Null", __func__);
1837 return -ENODEV;
1838 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05301839
1840 if (pHddStaCtx == NULL)
1841 {
1842 hddLog(VOS_TRACE_LEVEL_FATAL,
1843 "%s: HddStaCtx is Null", __func__);
1844 return -ENODEV;
1845 }
1846
Dino Mycledf0a5d92014-07-04 09:41:55 +05301847 /* check the LLStats Capability */
1848 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1849 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1850 {
1851 hddLog(VOS_TRACE_LEVEL_ERROR,
1852 FL("Link Layer Statistics not supported by Firmware"));
1853 return -EINVAL;
1854 }
1855
Sunil Duttc69bccb2014-05-26 21:30:20 +05301856
1857 if (!pAdapter->isLinkLayerStatsSet)
1858 {
1859 hddLog(VOS_TRACE_LEVEL_FATAL,
1860 "%s: isLinkLayerStatsSet : %d",
1861 __func__, pAdapter->isLinkLayerStatsSet);
1862 return -EINVAL;
1863 }
1864
Mukul Sharma10313ba2015-07-29 19:14:39 +05301865 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
1866 {
1867 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1868 "%s: Roaming in progress, so unable to proceed this request", __func__);
1869 return -EBUSY;
1870 }
1871
Sunil Duttc69bccb2014-05-26 21:30:20 +05301872 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1873 (struct nlattr *)data,
1874 data_len, qca_wlan_vendor_ll_get_policy))
1875 {
1876 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1877 return -EINVAL;
1878 }
1879
1880 if (!tb_vendor
1881 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1882 {
1883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1884 return -EINVAL;
1885 }
1886
1887 if (!tb_vendor
1888 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1889 {
1890 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1891 return -EINVAL;
1892 }
1893
Sunil Duttc69bccb2014-05-26 21:30:20 +05301894
Dino Mycledf0a5d92014-07-04 09:41:55 +05301895 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301896 nla_get_u32( tb_vendor[
1897 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301898 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301899 nla_get_u32( tb_vendor[
1900 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1901
Dino Mycled3d50022014-07-07 12:58:25 +05301902 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1903 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301904
1905 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301906 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
1907 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301908 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301909
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301910 spin_lock(&hdd_context_lock);
1911 context = &pHddCtx->ll_stats_context;
1912 context->request_id = linkLayerStatsGetReq.reqId;
1913 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
1914 INIT_COMPLETION(context->response_event);
1915 spin_unlock(&hdd_context_lock);
1916
Sunil Duttc69bccb2014-05-26 21:30:20 +05301917 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301918 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301919 {
1920 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1921 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301922 return -EINVAL;
1923 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301924
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301925 rc = wait_for_completion_timeout(&context->response_event,
1926 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
1927 if (!rc)
1928 {
1929 hddLog(LOGE,
1930 FL("Target response timed out request id %d request bitmap 0x%x"),
1931 context->request_id, context->request_bitmap);
1932 return -ETIMEDOUT;
1933 }
1934
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301935 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301936 return 0;
1937}
1938
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301939static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1940 struct wireless_dev *wdev,
1941 const void *data,
1942 int data_len)
1943{
1944 int ret = 0;
1945
1946 vos_ssr_protect(__func__);
1947 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1948 vos_ssr_unprotect(__func__);
1949
1950 return ret;
1951}
1952
Sunil Duttc69bccb2014-05-26 21:30:20 +05301953const struct
1954nla_policy
1955qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1956{
1957 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1958 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1959 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1960 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1961};
1962
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301963static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1964 struct wireless_dev *wdev,
1965 const void *data,
1966 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301967{
1968 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1969 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301970 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301971 struct net_device *dev = wdev->netdev;
1972 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1973 u32 statsClearReqMask;
1974 u8 stopReq;
1975 int status;
1976
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301977 ENTER();
1978
Sunil Duttc69bccb2014-05-26 21:30:20 +05301979 status = wlan_hdd_validate_context(pHddCtx);
1980 if (0 != status)
1981 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301982 return -EINVAL;
1983 }
1984
1985 if (NULL == pAdapter)
1986 {
1987 hddLog(VOS_TRACE_LEVEL_FATAL,
1988 "%s: HDD adapter is Null", __func__);
1989 return -ENODEV;
1990 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301991 /* check the LLStats Capability */
1992 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1993 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1994 {
1995 hddLog(VOS_TRACE_LEVEL_ERROR,
1996 FL("Enable LLStats Capability"));
1997 return -EINVAL;
1998 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301999
2000 if (!pAdapter->isLinkLayerStatsSet)
2001 {
2002 hddLog(VOS_TRACE_LEVEL_FATAL,
2003 "%s: isLinkLayerStatsSet : %d",
2004 __func__, pAdapter->isLinkLayerStatsSet);
2005 return -EINVAL;
2006 }
2007
2008 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2009 (struct nlattr *)data,
2010 data_len, qca_wlan_vendor_ll_clr_policy))
2011 {
2012 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2013 return -EINVAL;
2014 }
2015
2016 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2017
2018 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2019 {
2020 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2021 return -EINVAL;
2022
2023 }
2024
Sunil Duttc69bccb2014-05-26 21:30:20 +05302025
Dino Mycledf0a5d92014-07-04 09:41:55 +05302026 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302027 nla_get_u32(
2028 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2029
Dino Mycledf0a5d92014-07-04 09:41:55 +05302030 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302031 nla_get_u8(
2032 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2033
2034 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302035 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302036
Dino Mycled3d50022014-07-07 12:58:25 +05302037 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2038 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302039
2040 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302041 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2042 "statsClearReqMask = 0x%X, stopReq = %d",
2043 linkLayerStatsClearReq.reqId,
2044 linkLayerStatsClearReq.macAddr,
2045 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302046 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302047
2048 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302049 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302050 {
2051 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302052 hdd_station_ctx_t *pHddStaCtx;
2053
2054 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2055 if (VOS_STATUS_SUCCESS !=
2056 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2057 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2058 {
2059 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2060 "WLANTL_ClearInterfaceStats Failed", __func__);
2061 return -EINVAL;
2062 }
2063 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2064 (statsClearReqMask & WIFI_STATS_IFACE)) {
2065 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2066 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2067 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2068 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2069 }
2070
Sunil Duttc69bccb2014-05-26 21:30:20 +05302071 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2072 2 * sizeof(u32) +
2073 NLMSG_HDRLEN);
2074
2075 if (temp_skbuff != NULL)
2076 {
2077
2078 if (nla_put_u32(temp_skbuff,
2079 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2080 statsClearReqMask) ||
2081 nla_put_u32(temp_skbuff,
2082 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2083 stopReq))
2084 {
2085 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2086 kfree_skb(temp_skbuff);
2087 return -EINVAL;
2088 }
2089 /* If the ask is to stop the stats collection as part of clear
2090 * (stopReq = 1) , ensure that no further requests of get
2091 * go to the firmware by having isLinkLayerStatsSet set to 0.
2092 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302093 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302094 * case the firmware is just asked to clear the statistics.
2095 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302096 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302097 pAdapter->isLinkLayerStatsSet = 0;
2098 return cfg80211_vendor_cmd_reply(temp_skbuff);
2099 }
2100 return -ENOMEM;
2101 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302102
2103 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302104 return -EINVAL;
2105}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302106static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2107 struct wireless_dev *wdev,
2108 const void *data,
2109 int data_len)
2110{
2111 int ret = 0;
2112
2113 vos_ssr_protect(__func__);
2114 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2115 vos_ssr_unprotect(__func__);
2116
2117 return ret;
2118
2119
2120}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302121#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2122
Dino Mycle6fb96c12014-06-10 11:52:40 +05302123#ifdef WLAN_FEATURE_EXTSCAN
2124static const struct nla_policy
2125wlan_hdd_extscan_config_policy
2126 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2127{
2128 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2129 { .type = NLA_U32 },
2130 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2131 { .type = NLA_U32 },
2132 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2133 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2134 { .type = NLA_U32 },
2135 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2136 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2137
2138 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2139 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2140 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2141 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2142 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302143 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2144 { .type = NLA_U32 },
2145 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2146 { .type = NLA_U32 },
2147 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2148 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302149 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2150 { .type = NLA_U32 },
2151 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2152 { .type = NLA_U32 },
2153 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2154 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302155 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2156 { .type = NLA_U8 },
2157 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302158 { .type = NLA_U8 },
2159 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2160 { .type = NLA_U8 },
2161 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2162 { .type = NLA_U8 },
2163
2164 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2165 { .type = NLA_U32 },
2166 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2167 { .type = NLA_UNSPEC },
2168 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2169 { .type = NLA_S32 },
2170 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2171 { .type = NLA_S32 },
2172 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2173 { .type = NLA_U32 },
2174 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2175 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302176 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2177 { .type = NLA_U32 },
2178 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2179 { .type = NLA_BINARY,
2180 .len = IEEE80211_MAX_SSID_LEN + 1 },
2181 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302182 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302183 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2184 { .type = NLA_U32 },
2185 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2186 { .type = NLA_U8 },
2187 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2188 { .type = NLA_S32 },
2189 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2190 { .type = NLA_S32 },
2191 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2192 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302193};
2194
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302195/**
2196 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2197 * @ctx: hdd global context
2198 * @data: capabilities data
2199 *
2200 * Return: none
2201 */
2202static void
2203wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302204{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302205 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302206 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302207 tSirEXTScanCapabilitiesEvent *data =
2208 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302209
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302210 ENTER();
2211
2212 if (wlan_hdd_validate_context(pHddCtx))
2213 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302214 return;
2215 }
2216
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302217 if (!pMsg)
2218 {
2219 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2220 return;
2221 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302222
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302223 vos_spin_lock_acquire(&hdd_context_lock);
2224
2225 context = &pHddCtx->ext_scan_context;
2226 /* validate response received from target*/
2227 if (context->request_id != data->requestId)
2228 {
2229 vos_spin_lock_release(&hdd_context_lock);
2230 hddLog(LOGE,
2231 FL("Target response id did not match: request_id %d resposne_id %d"),
2232 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302233 return;
2234 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302235 else
2236 {
2237 context->capability_response = *data;
2238 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302239 }
2240
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302241 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302242
Dino Mycle6fb96c12014-06-10 11:52:40 +05302243 return;
2244}
2245
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302246/*
2247 * define short names for the global vendor params
2248 * used by wlan_hdd_send_ext_scan_capability()
2249 */
2250#define PARAM_REQUEST_ID \
2251 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2252#define PARAM_STATUS \
2253 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2254#define MAX_SCAN_CACHE_SIZE \
2255 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2256#define MAX_SCAN_BUCKETS \
2257 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2258#define MAX_AP_CACHE_PER_SCAN \
2259 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2260#define MAX_RSSI_SAMPLE_SIZE \
2261 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2262#define MAX_SCAN_RPT_THRHOLD \
2263 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2264#define MAX_HOTLIST_BSSIDS \
2265 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2266#define MAX_BSSID_HISTORY_ENTRIES \
2267 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2268#define MAX_HOTLIST_SSIDS \
2269 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302270#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2271 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302272
2273static int wlan_hdd_send_ext_scan_capability(void *ctx)
2274{
2275 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2276 struct sk_buff *skb = NULL;
2277 int ret;
2278 tSirEXTScanCapabilitiesEvent *data;
2279 tANI_U32 nl_buf_len;
2280
2281 ret = wlan_hdd_validate_context(pHddCtx);
2282 if (0 != ret)
2283 {
2284 return ret;
2285 }
2286
2287 data = &(pHddCtx->ext_scan_context.capability_response);
2288
2289 nl_buf_len = NLMSG_HDRLEN;
2290 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2291 (sizeof(data->status) + NLA_HDRLEN) +
2292 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2293 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2294 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2295 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2296 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2297 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2298 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2299 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2300
2301 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2302
2303 if (!skb)
2304 {
2305 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2306 return -ENOMEM;
2307 }
2308
2309 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2310 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2311 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2312 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2313 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2314 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2315 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2316 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2317
2318 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2319 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2320 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2321 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2322 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2323 data->maxApPerScan) ||
2324 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2325 data->maxRssiSampleSize) ||
2326 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2327 data->maxScanReportingThreshold) ||
2328 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2329 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2330 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302331 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2332 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302333 {
2334 hddLog(LOGE, FL("nla put fail"));
2335 goto nla_put_failure;
2336 }
2337
2338 cfg80211_vendor_cmd_reply(skb);
2339 return 0;
2340
2341nla_put_failure:
2342 kfree_skb(skb);
2343 return -EINVAL;;
2344}
2345
2346/*
2347 * done with short names for the global vendor params
2348 * used by wlan_hdd_send_ext_scan_capability()
2349 */
2350#undef PARAM_REQUEST_ID
2351#undef PARAM_STATUS
2352#undef MAX_SCAN_CACHE_SIZE
2353#undef MAX_SCAN_BUCKETS
2354#undef MAX_AP_CACHE_PER_SCAN
2355#undef MAX_RSSI_SAMPLE_SIZE
2356#undef MAX_SCAN_RPT_THRHOLD
2357#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302358#undef MAX_BSSID_HISTORY_ENTRIES
2359#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302360
2361static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2362{
2363 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2364 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302365 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302366 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302367
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302368 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302369
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302370 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302371 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302372
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302373 if (!pMsg)
2374 {
2375 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302376 return;
2377 }
2378
Dino Mycle6fb96c12014-06-10 11:52:40 +05302379 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2380 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2381
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302382 context = &pHddCtx->ext_scan_context;
2383 spin_lock(&hdd_context_lock);
2384 if (context->request_id == pData->requestId) {
2385 context->response_status = pData->status ? -EINVAL : 0;
2386 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302387 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302388 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302389
2390 /*
2391 * Store the Request ID for comparing with the requestID obtained
2392 * in other requests.HDD shall return a failure is the extscan_stop
2393 * request is issued with a different requestId as that of the
2394 * extscan_start request. Also, This requestId shall be used while
2395 * indicating the full scan results to the upper layers.
2396 * The requestId is stored with the assumption that the firmware
2397 * shall return the ext scan start request's requestId in ext scan
2398 * start response.
2399 */
2400 if (pData->status == 0)
2401 pMac->sme.extScanStartReqId = pData->requestId;
2402
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302403 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302404 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302405}
2406
2407
2408static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2409{
2410 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2411 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302412 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302413
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302414 ENTER();
2415
2416 if (wlan_hdd_validate_context(pHddCtx)){
2417 return;
2418 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302419
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302420 if (!pMsg)
2421 {
2422 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302423 return;
2424 }
2425
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302426 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2427 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302428
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302429 context = &pHddCtx->ext_scan_context;
2430 spin_lock(&hdd_context_lock);
2431 if (context->request_id == pData->requestId) {
2432 context->response_status = pData->status ? -EINVAL : 0;
2433 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302434 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302435 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302436
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302437 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302438 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302439}
2440
Dino Mycle6fb96c12014-06-10 11:52:40 +05302441static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2442 void *pMsg)
2443{
2444 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302445 tpSirEXTScanSetBssidHotListRspParams pData =
2446 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302447 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302448
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302449 ENTER();
2450
2451 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302452 return;
2453 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302454
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302455 if (!pMsg)
2456 {
2457 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2458 return;
2459 }
2460
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302461 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2462 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302463
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302464 context = &pHddCtx->ext_scan_context;
2465 spin_lock(&hdd_context_lock);
2466 if (context->request_id == pData->requestId) {
2467 context->response_status = pData->status ? -EINVAL : 0;
2468 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302469 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302470 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302471
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302472 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302473 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302474}
2475
2476static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2477 void *pMsg)
2478{
2479 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302480 tpSirEXTScanResetBssidHotlistRspParams pData =
2481 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302482 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302483
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302484 ENTER();
2485
2486 if (wlan_hdd_validate_context(pHddCtx)) {
2487 return;
2488 }
2489 if (!pMsg)
2490 {
2491 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302492 return;
2493 }
2494
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302495 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2496 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302497
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302498 context = &pHddCtx->ext_scan_context;
2499 spin_lock(&hdd_context_lock);
2500 if (context->request_id == pData->requestId) {
2501 context->response_status = pData->status ? -EINVAL : 0;
2502 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302503 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302504 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302505
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302506 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302507 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302508}
2509
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302510static void wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(void *ctx,
2511 void *pMsg)
2512{
2513 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2514 tpSirEXTScanSetSsidHotListRspParams pData =
2515 (tpSirEXTScanSetSsidHotListRspParams) pMsg;
2516 struct hdd_ext_scan_context *context;
2517
2518 if (wlan_hdd_validate_context(pHddCtx)){
2519 return;
2520 }
2521
2522 if (!pMsg)
2523 {
2524 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2525 return;
2526 }
2527
2528 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2529 pData->status);
2530
2531 context = &pHddCtx->ext_scan_context;
2532 spin_lock(&hdd_context_lock);
2533 if (context->request_id == pData->requestId) {
2534 context->response_status = pData->status ? -EINVAL : 0;
2535 complete(&context->response_event);
2536 }
2537 spin_unlock(&hdd_context_lock);
2538
2539 return;
2540}
2541
2542static void wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(void *ctx,
2543 void *pMsg)
2544{
2545 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2546 tpSirEXTScanResetSsidHotlistRspParams pData =
2547 (tpSirEXTScanResetSsidHotlistRspParams) pMsg;
2548 struct hdd_ext_scan_context *context;
2549
2550 if (wlan_hdd_validate_context(pHddCtx)) {
2551 return;
2552 }
2553 if (!pMsg)
2554 {
2555 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2556 return;
2557 }
2558
2559 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2560 pData->status);
2561
2562 context = &pHddCtx->ext_scan_context;
2563 spin_lock(&hdd_context_lock);
2564 if (context->request_id == pData->requestId) {
2565 context->response_status = pData->status ? -EINVAL : 0;
2566 complete(&context->response_event);
2567 }
2568 spin_unlock(&hdd_context_lock);
2569
2570 return;
2571}
2572
2573
Dino Mycle6fb96c12014-06-10 11:52:40 +05302574static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2575 void *pMsg)
2576{
2577 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2578 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302579 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302580 tANI_S32 totalResults;
2581 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302582 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
2583 struct hdd_ext_scan_context *context;
2584 bool ignore_cached_results = false;
2585 tExtscanCachedScanResult *result;
2586 struct nlattr *nla_results;
2587 tANI_U16 ieLength= 0;
2588 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302589
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302590 ENTER();
2591
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302592 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302593 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302594
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302595 if (!pMsg)
2596 {
2597 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2598 return;
2599 }
2600
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302601 spin_lock(&hdd_context_lock);
2602 context = &pHddCtx->ext_scan_context;
2603 ignore_cached_results = context->ignore_cached_results;
2604 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302605
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302606 if (ignore_cached_results) {
2607 hddLog(LOGE,
2608 FL("Ignore the cached results received after timeout"));
2609 return;
2610 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302611
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302612 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
2613 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302614
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302615 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302616
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302617 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
2618 scan_id_index++) {
2619 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302620
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302621 totalResults = result->num_results;
2622 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
2623 result->scan_id, result->flags, totalResults);
2624 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302625
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302626 do{
2627 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2628 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2629 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302630
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302631 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2632 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
2633
2634 if (!skb) {
2635 hddLog(VOS_TRACE_LEVEL_ERROR,
2636 FL("cfg80211_vendor_event_alloc failed"));
2637 return;
2638 }
2639
2640 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2641
2642 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2643 pData->requestId) ||
2644 nla_put_u32(skb,
2645 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2646 resultsPerEvent)) {
2647 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2648 goto fail;
2649 }
2650 if (nla_put_u8(skb,
2651 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2652 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302653 {
2654 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2655 goto fail;
2656 }
2657
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302658 if (nla_put_u32(skb,
2659 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2660 result->scan_id)) {
2661 hddLog(LOGE, FL("put fail"));
2662 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302663 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302664
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302665 nla_results = nla_nest_start(skb,
2666 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
2667 if (!nla_results)
2668 goto fail;
2669
2670 if (resultsPerEvent) {
2671 struct nlattr *aps;
2672 struct nlattr *nla_result;
2673
2674 nla_result = nla_nest_start(skb, scan_id_index);
2675 if(!nla_result)
2676 goto fail;
2677
2678 if (nla_put_u32(skb,
2679 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2680 result->scan_id) ||
2681 nla_put_u32(skb,
2682 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
2683 result->flags) ||
2684 nla_put_u32(skb,
2685 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2686 totalResults)) {
2687 hddLog(LOGE, FL("put fail"));
2688 goto fail;
2689 }
2690
2691 aps = nla_nest_start(skb,
2692 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2693 if (!aps)
2694 {
2695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2696 goto fail;
2697 }
2698
2699 head_ptr = (tpSirWifiScanResult) &(result->ap);
2700
2701 for (j = 0; j < resultsPerEvent; j++, i++) {
2702 struct nlattr *ap;
2703 pSirWifiScanResult = head_ptr + i;
2704
2705 /*
2706 * Firmware returns timestamp from WiFi turn ON till
2707 * BSSID was cached (in seconds). Add this with
2708 * time gap between system boot up to WiFi turn ON
2709 * to derive the time since boot when the
2710 * BSSID was cached.
2711 */
2712 pSirWifiScanResult->ts += pHddCtx->wifi_turn_on_time_since_boot;
2713 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2714 "Ssid (%s)"
2715 "Bssid: %pM "
2716 "Channel (%u)"
2717 "Rssi (%d)"
2718 "RTT (%u)"
2719 "RTT_SD (%u)"
2720 "Beacon Period %u"
2721 "Capability 0x%x "
2722 "Ie length %d",
2723 i,
2724 pSirWifiScanResult->ts,
2725 pSirWifiScanResult->ssid,
2726 pSirWifiScanResult->bssid,
2727 pSirWifiScanResult->channel,
2728 pSirWifiScanResult->rssi,
2729 pSirWifiScanResult->rtt,
2730 pSirWifiScanResult->rtt_sd,
2731 pSirWifiScanResult->beaconPeriod,
2732 pSirWifiScanResult->capability,
2733 ieLength);
2734
2735 ap = nla_nest_start(skb, j + 1);
2736 if (!ap)
2737 {
2738 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2739 goto fail;
2740 }
2741
2742 if (nla_put_u64(skb,
2743 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2744 pSirWifiScanResult->ts) )
2745 {
2746 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2747 goto fail;
2748 }
2749 if (nla_put(skb,
2750 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2751 sizeof(pSirWifiScanResult->ssid),
2752 pSirWifiScanResult->ssid) )
2753 {
2754 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2755 goto fail;
2756 }
2757 if (nla_put(skb,
2758 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2759 sizeof(pSirWifiScanResult->bssid),
2760 pSirWifiScanResult->bssid) )
2761 {
2762 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2763 goto fail;
2764 }
2765 if (nla_put_u32(skb,
2766 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2767 pSirWifiScanResult->channel) )
2768 {
2769 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2770 goto fail;
2771 }
2772 if (nla_put_s32(skb,
2773 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2774 pSirWifiScanResult->rssi) )
2775 {
2776 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2777 goto fail;
2778 }
2779 if (nla_put_u32(skb,
2780 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2781 pSirWifiScanResult->rtt) )
2782 {
2783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2784 goto fail;
2785 }
2786 if (nla_put_u32(skb,
2787 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2788 pSirWifiScanResult->rtt_sd))
2789 {
2790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2791 goto fail;
2792 }
2793 if (nla_put_u32(skb,
2794 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2795 pSirWifiScanResult->beaconPeriod))
2796 {
2797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2798 goto fail;
2799 }
2800 if (nla_put_u32(skb,
2801 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2802 pSirWifiScanResult->capability))
2803 {
2804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2805 goto fail;
2806 }
2807 if (nla_put_u32(skb,
2808 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2809 ieLength))
2810 {
2811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2812 goto fail;
2813 }
2814
2815 if (ieLength)
2816 if (nla_put(skb,
2817 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2818 ieLength, ie)) {
2819 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2820 goto fail;
2821 }
2822
2823 nla_nest_end(skb, ap);
2824 }
2825 nla_nest_end(skb, aps);
2826 nla_nest_end(skb, nla_result);
2827 }
2828
2829 nla_nest_end(skb, nla_results);
2830
2831 cfg80211_vendor_cmd_reply(skb);
2832
2833 } while (totalResults > 0);
2834 }
2835
2836 if (!pData->moreData) {
2837 spin_lock(&hdd_context_lock);
2838 context->response_status = 0;
2839 complete(&context->response_event);
2840 spin_unlock(&hdd_context_lock);
2841 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302842
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302843 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302844 return;
2845fail:
2846 kfree_skb(skb);
2847 return;
2848}
2849
2850static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2851 void *pMsg)
2852{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302853 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302854 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2855 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302856 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302857
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302858 ENTER();
2859
2860 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302861 hddLog(LOGE,
2862 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302863 return;
2864 }
2865 if (!pMsg)
2866 {
2867 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302868 return;
2869 }
2870
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302871 if (pData->bss_found)
2872 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2873 else
2874 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2875
Dino Mycle6fb96c12014-06-10 11:52:40 +05302876 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302877#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2878 NULL,
2879#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302880 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302881 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302882
2883 if (!skb) {
2884 hddLog(VOS_TRACE_LEVEL_ERROR,
2885 FL("cfg80211_vendor_event_alloc failed"));
2886 return;
2887 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302888
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302889 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2890 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2891 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2892 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2893
2894 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302895 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2896 "Ssid (%s) "
2897 "Bssid (" MAC_ADDRESS_STR ") "
2898 "Channel (%u) "
2899 "Rssi (%d) "
2900 "RTT (%u) "
2901 "RTT_SD (%u) ",
2902 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302903 pData->bssHotlist[i].ts,
2904 pData->bssHotlist[i].ssid,
2905 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2906 pData->bssHotlist[i].channel,
2907 pData->bssHotlist[i].rssi,
2908 pData->bssHotlist[i].rtt,
2909 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302910 }
2911
2912 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2913 pData->requestId) ||
2914 nla_put_u32(skb,
2915 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302916 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302917 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2918 goto fail;
2919 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302920 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302921 struct nlattr *aps;
2922
2923 aps = nla_nest_start(skb,
2924 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2925 if (!aps)
2926 goto fail;
2927
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302928 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302929 struct nlattr *ap;
2930
2931 ap = nla_nest_start(skb, i + 1);
2932 if (!ap)
2933 goto fail;
2934
2935 if (nla_put_u64(skb,
2936 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302937 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302938 nla_put(skb,
2939 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302940 sizeof(pData->bssHotlist[i].ssid),
2941 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302942 nla_put(skb,
2943 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302944 sizeof(pData->bssHotlist[i].bssid),
2945 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302946 nla_put_u32(skb,
2947 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302948 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302949 nla_put_s32(skb,
2950 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302951 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302952 nla_put_u32(skb,
2953 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302954 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302955 nla_put_u32(skb,
2956 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302957 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302958 goto fail;
2959
2960 nla_nest_end(skb, ap);
2961 }
2962 nla_nest_end(skb, aps);
2963
2964 if (nla_put_u8(skb,
2965 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2966 pData->moreData))
2967 goto fail;
2968 }
2969
2970 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302971 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302972 return;
2973
2974fail:
2975 kfree_skb(skb);
2976 return;
2977
2978}
Dino Mycle6fb96c12014-06-10 11:52:40 +05302979
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302980/**
2981 * wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind() -
2982 * Handle an SSID hotlist match event
2983 * @ctx: HDD context registered with SME
2984 * @event: The SSID hotlist match event
2985 *
2986 * This function will take an SSID match event that was generated by
2987 * firmware and will convert it into a cfg80211 vendor event which is
2988 * sent to userspace.
2989 *
2990 * Return: none
2991 */
2992static void
2993wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
2994 void *pMsg)
2995{
2996 hdd_context_t *hdd_ctx = ctx;
2997 struct sk_buff *skb;
2998 tANI_U32 i, index;
2999 tpSirEXTScanSsidHotlistMatch pData = (tpSirEXTScanSsidHotlistMatch) pMsg;
3000
3001 ENTER();
3002
3003 if (wlan_hdd_validate_context(hdd_ctx)) {
3004 hddLog(LOGE,
3005 FL("HDD context is not valid or response"));
3006 return;
3007 }
3008 if (!pMsg)
3009 {
3010 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3011 return;
3012 }
3013
3014 if (pData->ssid_found) {
3015 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX;
3016 hddLog(LOG1, "SSID hotlist found");
3017 } else {
3018 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX;
3019 hddLog(LOG1, "SSID hotlist lost");
3020 }
3021
3022 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
3023#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3024 NULL,
3025#endif
3026 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3027 index, GFP_KERNEL);
3028
3029 if (!skb) {
3030 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
3031 return;
3032 }
3033 hddLog(LOG1, "Req Id %u, Num of SSIDs %u, More Data (%u)",
3034 pData->requestId, pData->numHotlistSsid, pData->moreData);
3035
3036 for (i = 0; i < pData->numHotlistSsid; i++) {
3037 hddLog(LOG1, "[i=%d] Timestamp %llu "
3038 "Ssid: %s "
3039 "Bssid (" MAC_ADDRESS_STR ") "
3040 "Channel %u "
3041 "Rssi %d "
3042 "RTT %u "
3043 "RTT_SD %u",
3044 i,
3045 pData->ssidHotlist[i].ts,
3046 pData->ssidHotlist[i].ssid,
3047 MAC_ADDR_ARRAY(pData->ssidHotlist[i].bssid),
3048 pData->ssidHotlist[i].channel,
3049 pData->ssidHotlist[i].rssi,
3050 pData->ssidHotlist[i].rtt,
3051 pData->ssidHotlist[i].rtt_sd);
3052 }
3053
3054 if (nla_put_u32(skb,
3055 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3056 pData->requestId) ||
3057 nla_put_u32(skb,
3058 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3059 pData->numHotlistSsid)) {
3060 hddLog(LOGE, FL("put fail"));
3061 goto fail;
3062 }
3063
3064 if (pData->numHotlistSsid) {
3065 struct nlattr *aps;
3066 aps = nla_nest_start(skb,
3067 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3068 if (!aps) {
3069 hddLog(LOGE, FL("nest fail"));
3070 goto fail;
3071 }
3072
3073 for (i = 0; i < pData->numHotlistSsid; i++) {
3074 struct nlattr *ap;
3075
3076 ap = nla_nest_start(skb, i);
3077 if (!ap) {
3078 hddLog(LOGE, FL("nest fail"));
3079 goto fail;
3080 }
3081
3082 if (nla_put_u64(skb,
3083 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3084 pData->ssidHotlist[i].ts) ||
3085 nla_put(skb,
3086 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3087 sizeof(pData->ssidHotlist[i].ssid),
3088 pData->ssidHotlist[i].ssid) ||
3089 nla_put(skb,
3090 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3091 sizeof(pData->ssidHotlist[i].bssid),
3092 pData->ssidHotlist[i].bssid) ||
3093 nla_put_u32(skb,
3094 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3095 pData->ssidHotlist[i].channel) ||
3096 nla_put_s32(skb,
3097 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3098 pData->ssidHotlist[i].rssi) ||
3099 nla_put_u32(skb,
3100 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3101 pData->ssidHotlist[i].rtt) ||
3102 nla_put_u32(skb,
3103 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3104 pData->ssidHotlist[i].rtt_sd)) {
3105 hddLog(LOGE, FL("put fail"));
3106 goto fail;
3107 }
3108 nla_nest_end(skb, ap);
3109 }
3110 nla_nest_end(skb, aps);
3111
3112 if (nla_put_u8(skb,
3113 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3114 pData->moreData)) {
3115 hddLog(LOGE, FL("put fail"));
3116 goto fail;
3117 }
3118 }
3119
3120 cfg80211_vendor_event(skb, GFP_KERNEL);
3121 return;
3122
3123fail:
3124 kfree_skb(skb);
3125 return;
3126
3127}
3128
3129
Dino Mycle6fb96c12014-06-10 11:52:40 +05303130static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3131 void *pMsg)
3132{
3133 struct sk_buff *skb;
3134 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3135 tpSirWifiFullScanResultEvent pData =
3136 (tpSirWifiFullScanResultEvent) (pMsg);
3137
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303138 ENTER();
3139
3140 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303141 hddLog(LOGE,
3142 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303143 return;
3144 }
3145 if (!pMsg)
3146 {
3147 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303148 return;
3149 }
3150
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303151 /*
3152 * If the full scan result including IE data exceeds NL 4K size
3153 * limitation, drop that beacon/probe rsp frame.
3154 */
3155 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3156 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3157 return;
3158 }
3159
Dino Mycle6fb96c12014-06-10 11:52:40 +05303160 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303161#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3162 NULL,
3163#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303164 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3165 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3166 GFP_KERNEL);
3167
3168 if (!skb) {
3169 hddLog(VOS_TRACE_LEVEL_ERROR,
3170 FL("cfg80211_vendor_event_alloc failed"));
3171 return;
3172 }
3173
Dino Mycle6fb96c12014-06-10 11:52:40 +05303174 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3175 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3176 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3177 "Ssid (%s)"
3178 "Bssid (" MAC_ADDRESS_STR ")"
3179 "Channel (%u)"
3180 "Rssi (%d)"
3181 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303182 "RTT_SD (%u)"
3183 "Bcn Period %d"
3184 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303185 pData->ap.ts,
3186 pData->ap.ssid,
3187 MAC_ADDR_ARRAY(pData->ap.bssid),
3188 pData->ap.channel,
3189 pData->ap.rssi,
3190 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303191 pData->ap.rtt_sd,
3192 pData->ap.beaconPeriod,
3193 pData->ap.capability);
3194
Dino Mycle6fb96c12014-06-10 11:52:40 +05303195 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3196 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3197 pData->requestId) ||
3198 nla_put_u64(skb,
3199 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3200 pData->ap.ts) ||
3201 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3202 sizeof(pData->ap.ssid),
3203 pData->ap.ssid) ||
3204 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3205 WNI_CFG_BSSID_LEN,
3206 pData->ap.bssid) ||
3207 nla_put_u32(skb,
3208 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3209 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303210 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303211 pData->ap.rssi) ||
3212 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3213 pData->ap.rtt) ||
3214 nla_put_u32(skb,
3215 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3216 pData->ap.rtt_sd) ||
3217 nla_put_u16(skb,
3218 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3219 pData->ap.beaconPeriod) ||
3220 nla_put_u16(skb,
3221 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3222 pData->ap.capability) ||
3223 nla_put_u32(skb,
3224 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303225 pData->ieLength) ||
3226 nla_put_u8(skb,
3227 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3228 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303229 {
3230 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3231 goto nla_put_failure;
3232 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303233
3234 if (pData->ieLength) {
3235 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3236 pData->ieLength,
3237 pData->ie))
3238 {
3239 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3240 goto nla_put_failure;
3241 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303242 }
3243
3244 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303245 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303246 return;
3247
3248nla_put_failure:
3249 kfree_skb(skb);
3250 return;
3251}
3252
3253static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3254 void *pMsg)
3255{
3256 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3257 struct sk_buff *skb = NULL;
3258 tpSirEXTScanResultsAvailableIndParams pData =
3259 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3260
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303261 ENTER();
3262
3263 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303264 hddLog(LOGE,
3265 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303266 return;
3267 }
3268 if (!pMsg)
3269 {
3270 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303271 return;
3272 }
3273
3274 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303275#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3276 NULL,
3277#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303278 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3279 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3280 GFP_KERNEL);
3281
3282 if (!skb) {
3283 hddLog(VOS_TRACE_LEVEL_ERROR,
3284 FL("cfg80211_vendor_event_alloc failed"));
3285 return;
3286 }
3287
Dino Mycle6fb96c12014-06-10 11:52:40 +05303288 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3289 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3290 pData->numResultsAvailable);
3291 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3292 pData->requestId) ||
3293 nla_put_u32(skb,
3294 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3295 pData->numResultsAvailable)) {
3296 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3297 goto nla_put_failure;
3298 }
3299
3300 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303301 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303302 return;
3303
3304nla_put_failure:
3305 kfree_skb(skb);
3306 return;
3307}
3308
3309static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3310{
3311 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3312 struct sk_buff *skb = NULL;
3313 tpSirEXTScanProgressIndParams pData =
3314 (tpSirEXTScanProgressIndParams) pMsg;
3315
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303316 ENTER();
3317
3318 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303319 hddLog(LOGE,
3320 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303321 return;
3322 }
3323 if (!pMsg)
3324 {
3325 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303326 return;
3327 }
3328
3329 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303330#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3331 NULL,
3332#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303333 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3334 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3335 GFP_KERNEL);
3336
3337 if (!skb) {
3338 hddLog(VOS_TRACE_LEVEL_ERROR,
3339 FL("cfg80211_vendor_event_alloc failed"));
3340 return;
3341 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303342 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303343 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3344 pData->extScanEventType);
3345 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3346 pData->status);
3347
3348 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3349 pData->extScanEventType) ||
3350 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303351 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3352 pData->requestId) ||
3353 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303354 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3355 pData->status)) {
3356 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3357 goto nla_put_failure;
3358 }
3359
3360 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303361 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303362 return;
3363
3364nla_put_failure:
3365 kfree_skb(skb);
3366 return;
3367}
3368
3369void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3370 void *pMsg)
3371{
3372 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3373
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303374 ENTER();
3375
Dino Mycle6fb96c12014-06-10 11:52:40 +05303376 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303377 return;
3378 }
3379
3380 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3381
3382
3383 switch(evType) {
3384 case SIR_HAL_EXTSCAN_START_RSP:
3385 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3386 break;
3387
3388 case SIR_HAL_EXTSCAN_STOP_RSP:
3389 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3390 break;
3391 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3392 /* There is no need to send this response to upper layer
3393 Just log the message */
3394 hddLog(VOS_TRACE_LEVEL_INFO,
3395 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3396 break;
3397 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3398 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3399 break;
3400
3401 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3402 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3403 break;
3404
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303405 case SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP:
3406 wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(ctx, pMsg);
3407 break;
3408
3409 case SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP:
3410 wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(ctx, pMsg);
3411 break;
3412
Dino Mycle6fb96c12014-06-10 11:52:40 +05303413 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303414 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303415 break;
3416 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3417 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3418 break;
3419 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3420 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3421 break;
3422 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3423 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3424 break;
3425 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3426 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3427 break;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303428 case SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND:
3429 wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(ctx, pMsg);
3430 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303431 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3432 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3433 break;
3434 default:
3435 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3436 break;
3437 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303438 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303439}
3440
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303441static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3442 struct wireless_dev *wdev,
3443 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303444{
Dino Myclee8843b32014-07-04 14:21:45 +05303445 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303446 struct net_device *dev = wdev->netdev;
3447 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3448 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3449 struct nlattr
3450 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3451 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303452 struct hdd_ext_scan_context *context;
3453 unsigned long rc;
3454 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303455
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303456 ENTER();
3457
Dino Mycle6fb96c12014-06-10 11:52:40 +05303458 status = wlan_hdd_validate_context(pHddCtx);
3459 if (0 != status)
3460 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303461 return -EINVAL;
3462 }
Dino Myclee8843b32014-07-04 14:21:45 +05303463 /* check the EXTScan Capability */
3464 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3465 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3466 {
3467 hddLog(VOS_TRACE_LEVEL_ERROR,
3468 FL("EXTScan not enabled/supported by Firmware"));
3469 return -EINVAL;
3470 }
3471
Dino Mycle6fb96c12014-06-10 11:52:40 +05303472 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3473 data, dataLen,
3474 wlan_hdd_extscan_config_policy)) {
3475 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3476 return -EINVAL;
3477 }
3478
3479 /* Parse and fetch request Id */
3480 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3481 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3482 return -EINVAL;
3483 }
3484
Dino Myclee8843b32014-07-04 14:21:45 +05303485 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303486 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303487 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303488
Dino Myclee8843b32014-07-04 14:21:45 +05303489 reqMsg.sessionId = pAdapter->sessionId;
3490 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303491
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303492 vos_spin_lock_acquire(&hdd_context_lock);
3493 context = &pHddCtx->ext_scan_context;
3494 context->request_id = reqMsg.requestId;
3495 INIT_COMPLETION(context->response_event);
3496 vos_spin_lock_release(&hdd_context_lock);
3497
Dino Myclee8843b32014-07-04 14:21:45 +05303498 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303499 if (!HAL_STATUS_SUCCESS(status)) {
3500 hddLog(VOS_TRACE_LEVEL_ERROR,
3501 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303502 return -EINVAL;
3503 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303504
3505 rc = wait_for_completion_timeout(&context->response_event,
3506 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3507 if (!rc) {
3508 hddLog(LOGE, FL("Target response timed out"));
3509 return -ETIMEDOUT;
3510 }
3511
3512 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3513 if (ret)
3514 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3515
3516 return ret;
3517
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303518 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303519 return 0;
3520}
3521
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303522static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3523 struct wireless_dev *wdev,
3524 const void *data, int dataLen)
3525{
3526 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303527
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303528 vos_ssr_protect(__func__);
3529 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3530 vos_ssr_unprotect(__func__);
3531
3532 return ret;
3533}
3534
3535static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3536 struct wireless_dev *wdev,
3537 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303538{
Dino Myclee8843b32014-07-04 14:21:45 +05303539 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303540 struct net_device *dev = wdev->netdev;
3541 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3542 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3543 struct nlattr
3544 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3545 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303546 struct hdd_ext_scan_context *context;
3547 unsigned long rc;
3548 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303549
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303550 ENTER();
3551
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303552 if (VOS_FTM_MODE == hdd_get_conparam()) {
3553 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3554 return -EINVAL;
3555 }
3556
Dino Mycle6fb96c12014-06-10 11:52:40 +05303557 status = wlan_hdd_validate_context(pHddCtx);
3558 if (0 != status)
3559 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303560 return -EINVAL;
3561 }
Dino Myclee8843b32014-07-04 14:21:45 +05303562 /* check the EXTScan Capability */
3563 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3564 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3565 {
3566 hddLog(VOS_TRACE_LEVEL_ERROR,
3567 FL("EXTScan not enabled/supported by Firmware"));
3568 return -EINVAL;
3569 }
3570
Dino Mycle6fb96c12014-06-10 11:52:40 +05303571 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3572 data, dataLen,
3573 wlan_hdd_extscan_config_policy)) {
3574 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3575 return -EINVAL;
3576 }
3577 /* Parse and fetch request Id */
3578 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3579 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3580 return -EINVAL;
3581 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303582
Dino Myclee8843b32014-07-04 14:21:45 +05303583 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303584 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3585
Dino Myclee8843b32014-07-04 14:21:45 +05303586 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303587
Dino Myclee8843b32014-07-04 14:21:45 +05303588 reqMsg.sessionId = pAdapter->sessionId;
3589 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303590
3591 /* Parse and fetch flush parameter */
3592 if (!tb
3593 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3594 {
3595 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3596 goto failed;
3597 }
Dino Myclee8843b32014-07-04 14:21:45 +05303598 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303599 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3600
Dino Myclee8843b32014-07-04 14:21:45 +05303601 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303602
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303603 spin_lock(&hdd_context_lock);
3604 context = &pHddCtx->ext_scan_context;
3605 context->request_id = reqMsg.requestId;
3606 context->ignore_cached_results = false;
3607 INIT_COMPLETION(context->response_event);
3608 spin_unlock(&hdd_context_lock);
3609
Dino Myclee8843b32014-07-04 14:21:45 +05303610 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303611 if (!HAL_STATUS_SUCCESS(status)) {
3612 hddLog(VOS_TRACE_LEVEL_ERROR,
3613 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303614 return -EINVAL;
3615 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303616
3617 rc = wait_for_completion_timeout(&context->response_event,
3618 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3619 if (!rc) {
3620 hddLog(LOGE, FL("Target response timed out"));
3621 retval = -ETIMEDOUT;
3622 spin_lock(&hdd_context_lock);
3623 context->ignore_cached_results = true;
3624 spin_unlock(&hdd_context_lock);
3625 } else {
3626 spin_lock(&hdd_context_lock);
3627 retval = context->response_status;
3628 spin_unlock(&hdd_context_lock);
3629 }
3630
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303631 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303632 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303633
3634failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303635 return -EINVAL;
3636}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303637static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3638 struct wireless_dev *wdev,
3639 const void *data, int dataLen)
3640{
3641 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303642
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303643 vos_ssr_protect(__func__);
3644 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3645 vos_ssr_unprotect(__func__);
3646
3647 return ret;
3648}
3649
3650static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303651 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303652 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303653{
3654 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3655 struct net_device *dev = wdev->netdev;
3656 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3657 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3658 struct nlattr
3659 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3660 struct nlattr
3661 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3662 struct nlattr *apTh;
3663 eHalStatus status;
3664 tANI_U8 i = 0;
3665 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303666 struct hdd_ext_scan_context *context;
3667 tANI_U32 request_id;
3668 unsigned long rc;
3669 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303670
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303671 ENTER();
3672
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303673 if (VOS_FTM_MODE == hdd_get_conparam()) {
3674 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3675 return -EINVAL;
3676 }
3677
Dino Mycle6fb96c12014-06-10 11:52:40 +05303678 status = wlan_hdd_validate_context(pHddCtx);
3679 if (0 != status)
3680 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303681 return -EINVAL;
3682 }
Dino Myclee8843b32014-07-04 14:21:45 +05303683 /* check the EXTScan Capability */
3684 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3685 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3686 {
3687 hddLog(VOS_TRACE_LEVEL_ERROR,
3688 FL("EXTScan not enabled/supported by Firmware"));
3689 return -EINVAL;
3690 }
3691
Dino Mycle6fb96c12014-06-10 11:52:40 +05303692 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3693 data, dataLen,
3694 wlan_hdd_extscan_config_policy)) {
3695 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3696 return -EINVAL;
3697 }
3698
3699 /* Parse and fetch request Id */
3700 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3701 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3702 return -EINVAL;
3703 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303704 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3705 vos_mem_malloc(sizeof(*pReqMsg));
3706 if (!pReqMsg) {
3707 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3708 return -ENOMEM;
3709 }
3710
Dino Myclee8843b32014-07-04 14:21:45 +05303711
Dino Mycle6fb96c12014-06-10 11:52:40 +05303712 pReqMsg->requestId = nla_get_u32(
3713 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3714 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3715
3716 /* Parse and fetch number of APs */
3717 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3718 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3719 goto fail;
3720 }
3721
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303722 /* Parse and fetch lost ap sample size */
3723 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3724 hddLog(LOGE, FL("attr lost ap sample size failed"));
3725 goto fail;
3726 }
3727
3728 pReqMsg->lostBssidSampleSize = nla_get_u32(
3729 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3730 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3731
Dino Mycle6fb96c12014-06-10 11:52:40 +05303732 pReqMsg->sessionId = pAdapter->sessionId;
3733 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3734
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303735 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303736 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303737 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303738
3739 nla_for_each_nested(apTh,
3740 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3741 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3742 nla_data(apTh), nla_len(apTh),
3743 NULL)) {
3744 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3745 goto fail;
3746 }
3747
3748 /* Parse and fetch MAC address */
3749 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3750 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3751 goto fail;
3752 }
3753 memcpy(pReqMsg->ap[i].bssid, nla_data(
3754 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3755 sizeof(tSirMacAddr));
3756 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3757
3758 /* Parse and fetch low RSSI */
3759 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3760 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3761 goto fail;
3762 }
3763 pReqMsg->ap[i].low = nla_get_s32(
3764 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3765 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3766
3767 /* Parse and fetch high RSSI */
3768 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3769 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3770 goto fail;
3771 }
3772 pReqMsg->ap[i].high = nla_get_s32(
3773 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3774 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3775 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303776 i++;
3777 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303778
3779 context = &pHddCtx->ext_scan_context;
3780 spin_lock(&hdd_context_lock);
3781 INIT_COMPLETION(context->response_event);
3782 context->request_id = request_id = pReqMsg->requestId;
3783 spin_unlock(&hdd_context_lock);
3784
Dino Mycle6fb96c12014-06-10 11:52:40 +05303785 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3786 if (!HAL_STATUS_SUCCESS(status)) {
3787 hddLog(VOS_TRACE_LEVEL_ERROR,
3788 FL("sme_SetBssHotlist failed(err=%d)"), status);
3789 vos_mem_free(pReqMsg);
3790 return -EINVAL;
3791 }
3792
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303793 /* request was sent -- wait for the response */
3794 rc = wait_for_completion_timeout(&context->response_event,
3795 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3796
3797 if (!rc) {
3798 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3799 retval = -ETIMEDOUT;
3800 } else {
3801 spin_lock(&hdd_context_lock);
3802 if (context->request_id == request_id)
3803 retval = context->response_status;
3804 else
3805 retval = -EINVAL;
3806 spin_unlock(&hdd_context_lock);
3807 }
3808
Dino Myclee8843b32014-07-04 14:21:45 +05303809 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303810 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303811 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303812
3813fail:
3814 vos_mem_free(pReqMsg);
3815 return -EINVAL;
3816}
3817
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303818static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3819 struct wireless_dev *wdev,
3820 const void *data, int dataLen)
3821{
3822 int ret = 0;
3823
3824 vos_ssr_protect(__func__);
3825 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3826 dataLen);
3827 vos_ssr_unprotect(__func__);
3828
3829 return ret;
3830}
3831
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303832/*
3833 * define short names for the global vendor params
3834 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
3835 */
3836#define PARAM_MAX \
3837QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
3838#define PARAM_REQUEST_ID \
3839QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3840#define PARAMS_LOST_SSID_SAMPLE_SIZE \
3841QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE
3842#define PARAMS_NUM_SSID \
3843QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID
3844#define THRESHOLD_PARAM \
3845QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM
3846#define PARAM_SSID \
3847QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID
3848#define PARAM_BAND \
3849QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND
3850#define PARAM_RSSI_LOW \
3851QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW
3852#define PARAM_RSSI_HIGH \
3853QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH
3854
3855/**
3856 * __wlan_hdd_cfg80211_extscan_set_ssid_hotlist() - set ssid hot list
3857 * @wiphy: Pointer to wireless phy
3858 * @wdev: Pointer to wireless device
3859 * @data: Pointer to data
3860 * @data_len: Data length
3861 *
3862 * Return: 0 on success, negative errno on failure
3863 */
3864static int
3865__wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
3866 struct wireless_dev *wdev,
3867 const void *data,
3868 int data_len)
3869{
3870 tSirEXTScanSetSsidHotListReqParams *request;
3871 struct net_device *dev = wdev->netdev;
3872 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3873 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
3874 struct nlattr *tb[PARAM_MAX + 1];
3875 struct nlattr *tb2[PARAM_MAX + 1];
3876 struct nlattr *ssids;
3877 struct hdd_ext_scan_context *context;
3878 uint32_t request_id;
3879 char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1] = {'\0'};
3880 int ssid_len;
3881 eHalStatus status;
3882 int i, rem, retval;
3883 unsigned long rc;
3884
3885 ENTER();
3886
3887 if (VOS_FTM_MODE == hdd_get_conparam()) {
3888 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3889 return -EINVAL;
3890 }
3891
3892 retval = wlan_hdd_validate_context(hdd_ctx);
3893 if (0 != retval) {
3894 hddLog(LOGE, FL("HDD context is not valid"));
3895 return -EINVAL;
3896 }
3897
3898 /* check the EXTScan Capability */
3899 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
3900 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3901 {
3902 hddLog(VOS_TRACE_LEVEL_ERROR,
3903 FL("EXTScan not enabled/supported by Firmware"));
3904 return -EINVAL;
3905 }
3906
3907 if (nla_parse(tb, PARAM_MAX,
3908 data, data_len,
3909 wlan_hdd_extscan_config_policy)) {
3910 hddLog(LOGE, FL("Invalid ATTR"));
3911 return -EINVAL;
3912 }
3913
3914 request = vos_mem_malloc(sizeof(*request));
3915 if (!request) {
3916 hddLog(LOGE, FL("vos_mem_malloc failed"));
3917 return -ENOMEM;
3918 }
3919
3920 /* Parse and fetch request Id */
3921 if (!tb[PARAM_REQUEST_ID]) {
3922 hddLog(LOGE, FL("attr request id failed"));
3923 goto fail;
3924 }
3925
3926 request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
3927 hddLog(LOG1, FL("Request Id %d"), request->request_id);
3928
3929 /* Parse and fetch lost SSID sample size */
3930 if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
3931 hddLog(LOGE, FL("attr number of Ssid failed"));
3932 goto fail;
3933 }
3934 request->lost_ssid_sample_size =
3935 nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
3936 hddLog(LOG1, FL("Lost SSID Sample Size %d"),
3937 request->lost_ssid_sample_size);
3938
3939 /* Parse and fetch number of hotlist SSID */
3940 if (!tb[PARAMS_NUM_SSID]) {
3941 hddLog(LOGE, FL("attr number of Ssid failed"));
3942 goto fail;
3943 }
3944 request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
3945 hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
3946
3947 request->session_id = adapter->sessionId;
3948 hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
3949
3950 i = 0;
3951 nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
3952 if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
3953 hddLog(LOGE,
3954 FL("Too Many SSIDs, %d exceeds %d"),
3955 i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
3956 break;
3957 }
3958 if (nla_parse(tb2, PARAM_MAX,
3959 nla_data(ssids), nla_len(ssids),
3960 wlan_hdd_extscan_config_policy)) {
3961 hddLog(LOGE, FL("nla_parse failed"));
3962 goto fail;
3963 }
3964
3965 /* Parse and fetch SSID */
3966 if (!tb2[PARAM_SSID]) {
3967 hddLog(LOGE, FL("attr ssid failed"));
3968 goto fail;
3969 }
3970 nla_memcpy(ssid_string,
3971 tb2[PARAM_SSID],
3972 sizeof(ssid_string));
3973 hddLog(LOG1, FL("SSID %s"),
3974 ssid_string);
3975 ssid_len = strlen(ssid_string);
3976 memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
3977 request->ssid[i].ssid.length = ssid_len;
3978 request->ssid[i].ssid.ssId[ssid_len] = '\0';
3979 hddLog(LOG1, FL("After copying SSID %s"),
3980 request->ssid[i].ssid.ssId);
3981 hddLog(LOG1, FL("After copying length: %d"),
3982 ssid_len);
3983
3984 /* Parse and fetch low RSSI */
3985 if (!tb2[PARAM_BAND]) {
3986 hddLog(LOGE, FL("attr band failed"));
3987 goto fail;
3988 }
3989 request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
3990 hddLog(LOG1, FL("band %d"), request->ssid[i].band);
3991
3992 /* Parse and fetch low RSSI */
3993 if (!tb2[PARAM_RSSI_LOW]) {
3994 hddLog(LOGE, FL("attr low RSSI failed"));
3995 goto fail;
3996 }
3997 request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
3998 hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
3999
4000 /* Parse and fetch high RSSI */
4001 if (!tb2[PARAM_RSSI_HIGH]) {
4002 hddLog(LOGE, FL("attr high RSSI failed"));
4003 goto fail;
4004 }
4005 request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
4006 hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
4007 i++;
4008 }
4009
4010 context = &hdd_ctx->ext_scan_context;
4011 spin_lock(&hdd_context_lock);
4012 INIT_COMPLETION(context->response_event);
4013 context->request_id = request_id = request->request_id;
4014 spin_unlock(&hdd_context_lock);
4015
4016 status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
4017 if (!HAL_STATUS_SUCCESS(status)) {
4018 hddLog(LOGE,
4019 FL("sme_set_ssid_hotlist failed(err=%d)"), status);
4020 goto fail;
4021 }
4022
4023 vos_mem_free(request);
4024
4025 /* request was sent -- wait for the response */
4026 rc = wait_for_completion_timeout(&context->response_event,
4027 msecs_to_jiffies
4028 (WLAN_WAIT_TIME_EXTSCAN));
4029 if (!rc) {
4030 hddLog(LOGE, FL("sme_set_ssid_hotlist timed out"));
4031 retval = -ETIMEDOUT;
4032 } else {
4033 spin_lock(&hdd_context_lock);
4034 if (context->request_id == request_id)
4035 retval = context->response_status;
4036 else
4037 retval = -EINVAL;
4038 spin_unlock(&hdd_context_lock);
4039 }
4040
4041 return retval;
4042
4043fail:
4044 vos_mem_free(request);
4045 return -EINVAL;
4046}
4047
4048/*
4049 * done with short names for the global vendor params
4050 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4051 */
4052#undef PARAM_MAX
4053#undef PARAM_REQUEST_ID
4054#undef PARAMS_NUM_SSID
4055#undef THRESHOLD_PARAM
4056#undef PARAM_SSID
4057#undef PARAM_BAND
4058#undef PARAM_RSSI_LOW
4059#undef PARAM_RSSI_HIGH
4060
4061static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4062 struct wireless_dev *wdev,
4063 const void *data, int dataLen)
4064{
4065 int ret = 0;
4066
4067 vos_ssr_protect(__func__);
4068 ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
4069 dataLen);
4070 vos_ssr_unprotect(__func__);
4071
4072 return ret;
4073}
4074
4075static int
4076__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4077 struct wireless_dev *wdev,
4078 const void *data,
4079 int data_len)
4080{
4081 tSirEXTScanResetSsidHotlistReqParams request;
4082 struct net_device *dev = wdev->netdev;
4083 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4084 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4085 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4086 struct hdd_ext_scan_context *context;
4087 uint32_t request_id;
4088 eHalStatus status;
4089 int retval;
4090 unsigned long rc;
4091
4092 ENTER();
4093
4094 if (VOS_FTM_MODE == hdd_get_conparam()) {
4095 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4096 return -EINVAL;
4097 }
4098
4099 retval = wlan_hdd_validate_context(hdd_ctx);
4100 if (0 != retval) {
4101 hddLog(LOGE, FL("HDD context is not valid"));
4102 return -EINVAL;
4103 }
4104
4105 /* check the EXTScan Capability */
4106 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
4107 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4108 {
4109 hddLog(LOGE,
4110 FL("EXTScan not enabled/supported by Firmware"));
4111 return -EINVAL;
4112 }
4113
4114 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4115 data, data_len,
4116 wlan_hdd_extscan_config_policy)) {
4117 hddLog(LOGE, FL("Invalid ATTR"));
4118 return -EINVAL;
4119 }
4120
4121 /* Parse and fetch request Id */
4122 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4123 hddLog(LOGE, FL("attr request id failed"));
4124 return -EINVAL;
4125 }
4126
4127 request.requestId = nla_get_u32(
4128 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4129 request.sessionId = adapter->sessionId;
4130 hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
4131 request.sessionId);
4132
4133 context = &hdd_ctx->ext_scan_context;
4134 spin_lock(&hdd_context_lock);
4135 INIT_COMPLETION(context->response_event);
4136 context->request_id = request_id = request.requestId;
4137 spin_unlock(&hdd_context_lock);
4138
4139 status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
4140 if (!HAL_STATUS_SUCCESS(status)) {
4141 hddLog(LOGE,
4142 FL("sme_reset_ssid_hotlist failed(err=%d)"), status);
4143 return -EINVAL;
4144 }
4145
4146 /* request was sent -- wait for the response */
4147 rc = wait_for_completion_timeout(&context->response_event,
4148 msecs_to_jiffies
4149 (WLAN_WAIT_TIME_EXTSCAN));
4150 if (!rc) {
4151 hddLog(LOGE, FL("sme_reset_ssid_hotlist timed out"));
4152 retval = -ETIMEDOUT;
4153 } else {
4154 spin_lock(&hdd_context_lock);
4155 if (context->request_id == request_id)
4156 retval = context->response_status;
4157 else
4158 retval = -EINVAL;
4159 spin_unlock(&hdd_context_lock);
4160 }
4161
4162 return retval;
4163}
4164
4165static int
4166wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4167 struct wireless_dev *wdev,
4168 const void *data,
4169 int data_len)
4170{
4171 int ret;
4172
4173 vos_ssr_protect(__func__);
4174 ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
4175 data, data_len);
4176 vos_ssr_unprotect(__func__);
4177
4178 return ret;
4179}
4180
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304181static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304182 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304183 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304184{
4185 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4186 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4187 tANI_U8 numChannels = 0;
4188 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304189 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304190 tWifiBand wifiBand;
4191 eHalStatus status;
4192 struct sk_buff *replySkb;
4193 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304194 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304195
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304196 ENTER();
4197
Dino Mycle6fb96c12014-06-10 11:52:40 +05304198 status = wlan_hdd_validate_context(pHddCtx);
4199 if (0 != status)
4200 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304201 return -EINVAL;
4202 }
Dino Myclee8843b32014-07-04 14:21:45 +05304203
Dino Mycle6fb96c12014-06-10 11:52:40 +05304204 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4205 data, dataLen,
4206 wlan_hdd_extscan_config_policy)) {
4207 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4208 return -EINVAL;
4209 }
4210
4211 /* Parse and fetch request Id */
4212 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4213 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4214 return -EINVAL;
4215 }
4216 requestId = nla_get_u32(
4217 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4218 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4219
4220 /* Parse and fetch wifi band */
4221 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4222 {
4223 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4224 return -EINVAL;
4225 }
4226 wifiBand = nla_get_u32(
4227 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4228 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4229
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304230 /* Parse and fetch max channels */
4231 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4232 {
4233 hddLog(LOGE, FL("attr max channels failed"));
4234 return -EINVAL;
4235 }
4236 maxChannels = nla_get_u32(
4237 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4238 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4239
Dino Mycle6fb96c12014-06-10 11:52:40 +05304240 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
4241 wifiBand, ChannelList,
4242 &numChannels);
4243 if (eHAL_STATUS_SUCCESS != status) {
4244 hddLog(VOS_TRACE_LEVEL_ERROR,
4245 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4246 return -EINVAL;
4247 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304248
4249 numChannels = VOS_MIN(numChannels, maxChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304250 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304251
Dino Mycle6fb96c12014-06-10 11:52:40 +05304252 for (i = 0; i < numChannels; i++)
4253 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
4254
4255 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4256 sizeof(u32) * numChannels +
4257 NLMSG_HDRLEN);
4258
4259 if (!replySkb) {
4260 hddLog(VOS_TRACE_LEVEL_ERROR,
4261 FL("valid channels: buffer alloc fail"));
4262 return -EINVAL;
4263 }
4264 if (nla_put_u32(replySkb,
4265 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
4266 numChannels) ||
4267 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
4268 sizeof(u32) * numChannels, ChannelList)) {
4269
4270 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4271 kfree_skb(replySkb);
4272 return -EINVAL;
4273 }
4274
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304275 ret = cfg80211_vendor_cmd_reply(replySkb);
4276
4277 EXIT();
4278 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304279}
4280
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304281static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4282 struct wireless_dev *wdev,
4283 const void *data, int dataLen)
4284{
4285 int ret = 0;
4286
4287 vos_ssr_protect(__func__);
4288 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4289 dataLen);
4290 vos_ssr_unprotect(__func__);
4291
4292 return ret;
4293}
4294
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304295static int hdd_extscan_start_fill_bucket_channel_spec(
4296 hdd_context_t *pHddCtx,
4297 tpSirEXTScanStartReqParams pReqMsg,
4298 struct nlattr **tb)
4299{
4300 struct nlattr *bucket[
4301 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4302 struct nlattr *channel[
4303 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4304 struct nlattr *buckets;
4305 struct nlattr *channels;
4306 int rem1, rem2;
4307 eHalStatus status;
4308 tANI_U8 bktIndex, j, numChannels;
4309 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4310 tANI_U32 passive_max_chn_time, active_max_chn_time;
4311
4312 bktIndex = 0;
4313
4314 nla_for_each_nested(buckets,
4315 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4316 if (nla_parse(bucket,
4317 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4318 nla_data(buckets), nla_len(buckets), NULL)) {
4319 hddLog(LOGE, FL("nla_parse failed"));
4320 return -EINVAL;
4321 }
4322
4323 /* Parse and fetch bucket spec */
4324 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4325 hddLog(LOGE, FL("attr bucket index failed"));
4326 return -EINVAL;
4327 }
4328 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4329 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4330 hddLog(LOG1, FL("Bucket spec Index %d"),
4331 pReqMsg->buckets[bktIndex].bucket);
4332
4333 /* Parse and fetch wifi band */
4334 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4335 hddLog(LOGE, FL("attr wifi band failed"));
4336 return -EINVAL;
4337 }
4338 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4339 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4340 hddLog(LOG1, FL("Wifi band %d"),
4341 pReqMsg->buckets[bktIndex].band);
4342
4343 /* Parse and fetch period */
4344 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4345 hddLog(LOGE, FL("attr period failed"));
4346 return -EINVAL;
4347 }
4348 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4349 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4350 hddLog(LOG1, FL("period %d"),
4351 pReqMsg->buckets[bktIndex].period);
4352
4353 /* Parse and fetch report events */
4354 if (!bucket[
4355 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4356 hddLog(LOGE, FL("attr report events failed"));
4357 return -EINVAL;
4358 }
4359 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4360 bucket[
4361 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4362 hddLog(LOG1, FL("report events %d"),
4363 pReqMsg->buckets[bktIndex].reportEvents);
4364
4365 /* Parse and fetch max period */
4366 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4367 hddLog(LOGE, FL("attr max period failed"));
4368 return -EINVAL;
4369 }
4370 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4371 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4372 hddLog(LOG1, FL("max period %u"),
4373 pReqMsg->buckets[bktIndex].max_period);
4374
4375 /* Parse and fetch exponent */
4376 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4377 hddLog(LOGE, FL("attr exponent failed"));
4378 return -EINVAL;
4379 }
4380 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4381 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4382 hddLog(LOG1, FL("exponent %u"),
4383 pReqMsg->buckets[bktIndex].exponent);
4384
4385 /* Parse and fetch step count */
4386 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4387 hddLog(LOGE, FL("attr step count failed"));
4388 return -EINVAL;
4389 }
4390 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4391 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4392 hddLog(LOG1, FL("Step count %u"),
4393 pReqMsg->buckets[bktIndex].step_count);
4394
4395 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4396 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4397
4398 /* Framework shall pass the channel list if the input WiFi band is
4399 * WIFI_BAND_UNSPECIFIED.
4400 * If the input WiFi band is specified (any value other than
4401 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4402 */
4403 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4404 numChannels = 0;
4405 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4406 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4407 pReqMsg->buckets[bktIndex].band,
4408 chanList, &numChannels);
4409 if (!HAL_STATUS_SUCCESS(status)) {
4410 hddLog(LOGE,
4411 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4412 status);
4413 return -EINVAL;
4414 }
4415
4416 pReqMsg->buckets[bktIndex].numChannels =
4417 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4418 hddLog(LOG1, FL("Num channels %d"),
4419 pReqMsg->buckets[bktIndex].numChannels);
4420
4421 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4422 j++) {
4423 pReqMsg->buckets[bktIndex].channels[j].channel =
4424 chanList[j];
4425 pReqMsg->buckets[bktIndex].channels[j].
4426 chnlClass = 0;
4427 if (CSR_IS_CHANNEL_DFS(
4428 vos_freq_to_chan(chanList[j]))) {
4429 pReqMsg->buckets[bktIndex].channels[j].
4430 passive = 1;
4431 pReqMsg->buckets[bktIndex].channels[j].
4432 dwellTimeMs = passive_max_chn_time;
4433 } else {
4434 pReqMsg->buckets[bktIndex].channels[j].
4435 passive = 0;
4436 pReqMsg->buckets[bktIndex].channels[j].
4437 dwellTimeMs = active_max_chn_time;
4438 }
4439
4440 hddLog(LOG1,
4441 "Channel %u Passive %u Dwell time %u ms",
4442 pReqMsg->buckets[bktIndex].channels[j].channel,
4443 pReqMsg->buckets[bktIndex].channels[j].passive,
4444 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4445 }
4446
4447 bktIndex++;
4448 continue;
4449 }
4450
4451 /* Parse and fetch number of channels */
4452 if (!bucket[
4453 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4454 hddLog(LOGE, FL("attr num channels failed"));
4455 return -EINVAL;
4456 }
4457
4458 pReqMsg->buckets[bktIndex].numChannels =
4459 nla_get_u32(bucket[
4460 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4461 hddLog(LOG1, FL("num channels %d"),
4462 pReqMsg->buckets[bktIndex].numChannels);
4463
4464 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4465 hddLog(LOGE, FL("attr channel spec failed"));
4466 return -EINVAL;
4467 }
4468
4469 j = 0;
4470 nla_for_each_nested(channels,
4471 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4472 if (nla_parse(channel,
4473 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4474 nla_data(channels), nla_len(channels),
4475 wlan_hdd_extscan_config_policy)) {
4476 hddLog(LOGE, FL("nla_parse failed"));
4477 return -EINVAL;
4478 }
4479
4480 /* Parse and fetch channel */
4481 if (!channel[
4482 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4483 hddLog(LOGE, FL("attr channel failed"));
4484 return -EINVAL;
4485 }
4486 pReqMsg->buckets[bktIndex].channels[j].channel =
4487 nla_get_u32(channel[
4488 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4489 hddLog(LOG1, FL("channel %u"),
4490 pReqMsg->buckets[bktIndex].channels[j].channel);
4491
4492 /* Parse and fetch dwell time */
4493 if (!channel[
4494 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4495 hddLog(LOGE, FL("attr dwelltime failed"));
4496 return -EINVAL;
4497 }
4498 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4499 nla_get_u32(channel[
4500 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4501
4502 hddLog(LOG1, FL("Dwell time (%u ms)"),
4503 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4504
4505
4506 /* Parse and fetch channel spec passive */
4507 if (!channel[
4508 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4509 hddLog(LOGE,
4510 FL("attr channel spec passive failed"));
4511 return -EINVAL;
4512 }
4513 pReqMsg->buckets[bktIndex].channels[j].passive =
4514 nla_get_u8(channel[
4515 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4516 hddLog(LOG1, FL("Chnl spec passive %u"),
4517 pReqMsg->buckets[bktIndex].channels[j].passive);
4518
4519 j++;
4520 }
4521
4522 bktIndex++;
4523 }
4524
4525 return 0;
4526}
4527
4528
4529/*
4530 * define short names for the global vendor params
4531 * used by wlan_hdd_cfg80211_extscan_start()
4532 */
4533#define PARAM_MAX \
4534QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4535#define PARAM_REQUEST_ID \
4536QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4537#define PARAM_BASE_PERIOD \
4538QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4539#define PARAM_MAX_AP_PER_SCAN \
4540QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4541#define PARAM_RPT_THRHLD_PERCENT \
4542QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4543#define PARAM_RPT_THRHLD_NUM_SCANS \
4544QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4545#define PARAM_NUM_BUCKETS \
4546QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4547
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304548static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304549 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304550 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304551{
Dino Myclee8843b32014-07-04 14:21:45 +05304552 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304553 struct net_device *dev = wdev->netdev;
4554 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4555 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4556 struct nlattr *tb[PARAM_MAX + 1];
4557 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304558 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304559 tANI_U32 request_id;
4560 struct hdd_ext_scan_context *context;
4561 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304562
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304563 ENTER();
4564
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304565 if (VOS_FTM_MODE == hdd_get_conparam()) {
4566 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4567 return -EINVAL;
4568 }
4569
Dino Mycle6fb96c12014-06-10 11:52:40 +05304570 status = wlan_hdd_validate_context(pHddCtx);
4571 if (0 != status)
4572 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304573 return -EINVAL;
4574 }
Dino Myclee8843b32014-07-04 14:21:45 +05304575 /* check the EXTScan Capability */
4576 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4577 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4578 {
4579 hddLog(VOS_TRACE_LEVEL_ERROR,
4580 FL("EXTScan not enabled/supported by Firmware"));
4581 return -EINVAL;
4582 }
4583
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304584 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304585 data, dataLen,
4586 wlan_hdd_extscan_config_policy)) {
4587 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4588 return -EINVAL;
4589 }
4590
4591 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304592 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304593 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4594 return -EINVAL;
4595 }
4596
Dino Myclee8843b32014-07-04 14:21:45 +05304597 pReqMsg = (tpSirEXTScanStartReqParams)
4598 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304599 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304600 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4601 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304602 }
4603
4604 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304605 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304606 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4607
4608 pReqMsg->sessionId = pAdapter->sessionId;
4609 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4610
4611 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304612 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304613 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4614 goto fail;
4615 }
4616 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304617 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304618 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4619 pReqMsg->basePeriod);
4620
4621 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304622 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304623 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4624 goto fail;
4625 }
4626 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304627 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304628 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4629 pReqMsg->maxAPperScan);
4630
4631 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304632 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304633 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4634 goto fail;
4635 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304636 pReqMsg->reportThresholdPercent = nla_get_u8(
4637 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304638 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304639 pReqMsg->reportThresholdPercent);
4640
4641 /* Parse and fetch report threshold num scans */
4642 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4643 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4644 goto fail;
4645 }
4646 pReqMsg->reportThresholdNumScans = nla_get_u8(
4647 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4648 hddLog(LOG1, FL("Report Threshold num scans %d"),
4649 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304650
4651 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304652 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4654 goto fail;
4655 }
4656 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304657 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304658 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4659 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4660 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4661 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4662 }
4663 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4664 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304665
Dino Mycle6fb96c12014-06-10 11:52:40 +05304666 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4668 goto fail;
4669 }
4670
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304671 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304672
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304673 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4674 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304675
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304676 context = &pHddCtx->ext_scan_context;
4677 spin_lock(&hdd_context_lock);
4678 INIT_COMPLETION(context->response_event);
4679 context->request_id = request_id = pReqMsg->requestId;
4680 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304681
Dino Mycle6fb96c12014-06-10 11:52:40 +05304682 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4683 if (!HAL_STATUS_SUCCESS(status)) {
4684 hddLog(VOS_TRACE_LEVEL_ERROR,
4685 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304686 goto fail;
4687 }
4688
4689 /* request was sent -- wait for the response */
4690 rc = wait_for_completion_timeout(&context->response_event,
4691 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4692
4693 if (!rc) {
4694 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4695 retval = -ETIMEDOUT;
4696 } else {
4697 spin_lock(&hdd_context_lock);
4698 if (context->request_id == request_id)
4699 retval = context->response_status;
4700 else
4701 retval = -EINVAL;
4702 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304703 }
4704
Dino Myclee8843b32014-07-04 14:21:45 +05304705 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304706 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304707 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304708
4709fail:
4710 vos_mem_free(pReqMsg);
4711 return -EINVAL;
4712}
4713
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304714/*
4715 * done with short names for the global vendor params
4716 * used by wlan_hdd_cfg80211_extscan_start()
4717 */
4718#undef PARAM_MAX
4719#undef PARAM_REQUEST_ID
4720#undef PARAM_BASE_PERIOD
4721#undef PARAMS_MAX_AP_PER_SCAN
4722#undef PARAMS_RPT_THRHLD_PERCENT
4723#undef PARAMS_RPT_THRHLD_NUM_SCANS
4724#undef PARAMS_NUM_BUCKETS
4725
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304726static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4727 struct wireless_dev *wdev,
4728 const void *data, int dataLen)
4729{
4730 int ret = 0;
4731
4732 vos_ssr_protect(__func__);
4733 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4734 vos_ssr_unprotect(__func__);
4735
4736 return ret;
4737}
4738
4739static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304740 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304741 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304742{
Dino Myclee8843b32014-07-04 14:21:45 +05304743 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304744 struct net_device *dev = wdev->netdev;
4745 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4746 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4747 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4748 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304749 int retval;
4750 unsigned long rc;
4751 struct hdd_ext_scan_context *context;
4752 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304753
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304754 ENTER();
4755
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304756 if (VOS_FTM_MODE == hdd_get_conparam()) {
4757 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4758 return -EINVAL;
4759 }
4760
Dino Mycle6fb96c12014-06-10 11:52:40 +05304761 status = wlan_hdd_validate_context(pHddCtx);
4762 if (0 != status)
4763 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304764 return -EINVAL;
4765 }
Dino Myclee8843b32014-07-04 14:21:45 +05304766 /* check the EXTScan Capability */
4767 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4768 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4769 {
4770 hddLog(VOS_TRACE_LEVEL_ERROR,
4771 FL("EXTScan not enabled/supported by Firmware"));
4772 return -EINVAL;
4773 }
4774
Dino Mycle6fb96c12014-06-10 11:52:40 +05304775 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4776 data, dataLen,
4777 wlan_hdd_extscan_config_policy)) {
4778 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4779 return -EINVAL;
4780 }
4781
4782 /* Parse and fetch request Id */
4783 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4784 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4785 return -EINVAL;
4786 }
4787
Dino Myclee8843b32014-07-04 14:21:45 +05304788 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304789 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304790 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304791
Dino Myclee8843b32014-07-04 14:21:45 +05304792 reqMsg.sessionId = pAdapter->sessionId;
4793 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304794
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304795 context = &pHddCtx->ext_scan_context;
4796 spin_lock(&hdd_context_lock);
4797 INIT_COMPLETION(context->response_event);
4798 context->request_id = request_id = reqMsg.sessionId;
4799 spin_unlock(&hdd_context_lock);
4800
Dino Myclee8843b32014-07-04 14:21:45 +05304801 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304802 if (!HAL_STATUS_SUCCESS(status)) {
4803 hddLog(VOS_TRACE_LEVEL_ERROR,
4804 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304805 return -EINVAL;
4806 }
4807
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304808 /* request was sent -- wait for the response */
4809 rc = wait_for_completion_timeout(&context->response_event,
4810 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4811
4812 if (!rc) {
4813 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4814 retval = -ETIMEDOUT;
4815 } else {
4816 spin_lock(&hdd_context_lock);
4817 if (context->request_id == request_id)
4818 retval = context->response_status;
4819 else
4820 retval = -EINVAL;
4821 spin_unlock(&hdd_context_lock);
4822 }
4823
4824 return retval;
4825
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304826 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304827 return 0;
4828}
4829
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304830static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4831 struct wireless_dev *wdev,
4832 const void *data, int dataLen)
4833{
4834 int ret = 0;
4835
4836 vos_ssr_protect(__func__);
4837 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4838 vos_ssr_unprotect(__func__);
4839
4840 return ret;
4841}
4842
4843static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304844 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304845 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304846{
Dino Myclee8843b32014-07-04 14:21:45 +05304847 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304848 struct net_device *dev = wdev->netdev;
4849 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4850 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4851 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4852 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304853 struct hdd_ext_scan_context *context;
4854 tANI_U32 request_id;
4855 unsigned long rc;
4856 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304857
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304858 ENTER();
4859
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304860 if (VOS_FTM_MODE == hdd_get_conparam()) {
4861 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4862 return -EINVAL;
4863 }
4864
Dino Mycle6fb96c12014-06-10 11:52:40 +05304865 status = wlan_hdd_validate_context(pHddCtx);
4866 if (0 != status)
4867 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304868 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304869 return -EINVAL;
4870 }
Dino Myclee8843b32014-07-04 14:21:45 +05304871 /* check the EXTScan Capability */
4872 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4873 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4874 {
4875 hddLog(VOS_TRACE_LEVEL_ERROR,
4876 FL("EXTScan not enabled/supported by Firmware"));
4877 return -EINVAL;
4878 }
4879
Dino Mycle6fb96c12014-06-10 11:52:40 +05304880 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4881 data, dataLen,
4882 wlan_hdd_extscan_config_policy)) {
4883 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4884 return -EINVAL;
4885 }
4886
4887 /* Parse and fetch request Id */
4888 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4889 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4890 return -EINVAL;
4891 }
4892
Dino Myclee8843b32014-07-04 14:21:45 +05304893 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304894 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304895 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304896
Dino Myclee8843b32014-07-04 14:21:45 +05304897 reqMsg.sessionId = pAdapter->sessionId;
4898 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304899
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304900 context = &pHddCtx->ext_scan_context;
4901 spin_lock(&hdd_context_lock);
4902 INIT_COMPLETION(context->response_event);
4903 context->request_id = request_id = reqMsg.requestId;
4904 spin_unlock(&hdd_context_lock);
4905
Dino Myclee8843b32014-07-04 14:21:45 +05304906 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304907 if (!HAL_STATUS_SUCCESS(status)) {
4908 hddLog(VOS_TRACE_LEVEL_ERROR,
4909 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304910 return -EINVAL;
4911 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304912
4913 /* request was sent -- wait for the response */
4914 rc = wait_for_completion_timeout(&context->response_event,
4915 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4916 if (!rc) {
4917 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4918 retval = -ETIMEDOUT;
4919 } else {
4920 spin_lock(&hdd_context_lock);
4921 if (context->request_id == request_id)
4922 retval = context->response_status;
4923 else
4924 retval = -EINVAL;
4925 spin_unlock(&hdd_context_lock);
4926 }
4927
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304928 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304929 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304930}
4931
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304932static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4933 struct wireless_dev *wdev,
4934 const void *data, int dataLen)
4935{
4936 int ret = 0;
4937
4938 vos_ssr_protect(__func__);
4939 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4940 vos_ssr_unprotect(__func__);
4941
4942 return ret;
4943}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304944#endif /* WLAN_FEATURE_EXTSCAN */
4945
Atul Mittal115287b2014-07-08 13:26:33 +05304946/*EXT TDLS*/
4947static const struct nla_policy
4948wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4949{
4950 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4951 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4952 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4953 {.type = NLA_S32 },
4954 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4955 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4956
4957};
4958
4959static const struct nla_policy
4960wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4961{
4962 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4963
4964};
4965
4966static const struct nla_policy
4967wlan_hdd_tdls_config_state_change_policy[
4968 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4969{
4970 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4971 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4972 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304973 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4974 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4975 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304976
4977};
4978
4979static const struct nla_policy
4980wlan_hdd_tdls_config_get_status_policy[
4981 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4982{
4983 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4984 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4985 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304986 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4987 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4988 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304989
4990};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304991
4992static const struct nla_policy
4993wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4994{
4995 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
4996};
4997
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304998static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304999 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305000 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305001 int data_len)
5002{
5003
5004 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5005 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5006
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305007 ENTER();
5008
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305009 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305010 return -EINVAL;
5011 }
5012 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305013 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305014 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305015 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305016 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305017 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305018 return -ENOTSUPP;
5019 }
5020
5021 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5022 data, data_len, wlan_hdd_mac_config)) {
5023 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5024 return -EINVAL;
5025 }
5026
5027 /* Parse and fetch mac address */
5028 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5029 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5030 return -EINVAL;
5031 }
5032
5033 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5034 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5035 VOS_MAC_ADDR_LAST_3_BYTES);
5036
Siddharth Bhal76972212014-10-15 16:22:51 +05305037 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5038
5039 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305040 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5041 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305042 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5043 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5044 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5045 {
5046 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5047 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5048 VOS_MAC_ADDRESS_LEN);
5049 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305050 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305051
Siddharth Bhal76972212014-10-15 16:22:51 +05305052 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
5053 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305054 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
5055 }
5056
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305057 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305058 return 0;
5059}
5060
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305061static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5062 struct wireless_dev *wdev,
5063 const void *data,
5064 int data_len)
5065{
5066 int ret = 0;
5067
5068 vos_ssr_protect(__func__);
5069 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5070 vos_ssr_unprotect(__func__);
5071
5072 return ret;
5073}
5074
5075static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305076 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305077 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305078 int data_len)
5079{
5080 u8 peer[6] = {0};
5081 struct net_device *dev = wdev->netdev;
5082 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5083 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5084 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5085 eHalStatus ret;
5086 tANI_S32 state;
5087 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305088 tANI_S32 global_operating_class = 0;
5089 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305090 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305091 int retVal;
5092
5093 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305094
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305095 if (!pAdapter) {
5096 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5097 return -EINVAL;
5098 }
5099
Atul Mittal115287b2014-07-08 13:26:33 +05305100 ret = wlan_hdd_validate_context(pHddCtx);
5101 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305102 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305103 return -EINVAL;
5104 }
5105 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305106 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305107 return -ENOTSUPP;
5108 }
5109 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5110 data, data_len,
5111 wlan_hdd_tdls_config_get_status_policy)) {
5112 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5113 return -EINVAL;
5114 }
5115
5116 /* Parse and fetch mac address */
5117 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5118 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5119 return -EINVAL;
5120 }
5121
5122 memcpy(peer, nla_data(
5123 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5124 sizeof(peer));
5125 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5126
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305127 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305128
Atul Mittal115287b2014-07-08 13:26:33 +05305129 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305130 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305131 NLMSG_HDRLEN);
5132
5133 if (!skb) {
5134 hddLog(VOS_TRACE_LEVEL_ERROR,
5135 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5136 return -EINVAL;
5137 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305138 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) class (%d) channel (%d) peer" MAC_ADDRESS_STR),
Atul Mittal115287b2014-07-08 13:26:33 +05305139 reason,
5140 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305141 global_operating_class,
5142 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305143 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305144 if (nla_put_s32(skb,
5145 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5146 state) ||
5147 nla_put_s32(skb,
5148 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5149 reason) ||
5150 nla_put_s32(skb,
5151 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5152 global_operating_class) ||
5153 nla_put_s32(skb,
5154 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5155 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305156
5157 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5158 goto nla_put_failure;
5159 }
5160
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305161 retVal = cfg80211_vendor_cmd_reply(skb);
5162 EXIT();
5163 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305164
5165nla_put_failure:
5166 kfree_skb(skb);
5167 return -EINVAL;
5168}
5169
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305170static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5171 struct wireless_dev *wdev,
5172 const void *data,
5173 int data_len)
5174{
5175 int ret = 0;
5176
5177 vos_ssr_protect(__func__);
5178 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5179 vos_ssr_unprotect(__func__);
5180
5181 return ret;
5182}
5183
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305184static int wlan_hdd_cfg80211_exttdls_callback(
5185#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5186 const tANI_U8* mac,
5187#else
5188 tANI_U8* mac,
5189#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305190 tANI_S32 state,
5191 tANI_S32 reason,
5192 void *ctx)
5193{
5194 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305195 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305196 tANI_S32 global_operating_class = 0;
5197 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305198 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305199
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305200 ENTER();
5201
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305202 if (!pAdapter) {
5203 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5204 return -EINVAL;
5205 }
5206
5207 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305208 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305209 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305210 return -EINVAL;
5211 }
5212
5213 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305214 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305215 return -ENOTSUPP;
5216 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305217 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5218#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5219 NULL,
5220#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305221 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5222 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5223 GFP_KERNEL);
5224
5225 if (!skb) {
5226 hddLog(VOS_TRACE_LEVEL_ERROR,
5227 FL("cfg80211_vendor_event_alloc failed"));
5228 return -EINVAL;
5229 }
5230 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305231 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5232 reason,
5233 state,
5234 global_operating_class,
5235 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305236 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5237 MAC_ADDR_ARRAY(mac));
5238
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305239 if (nla_put(skb,
5240 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5241 VOS_MAC_ADDR_SIZE, mac) ||
5242 nla_put_s32(skb,
5243 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5244 state) ||
5245 nla_put_s32(skb,
5246 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5247 reason) ||
5248 nla_put_s32(skb,
5249 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5250 channel) ||
5251 nla_put_s32(skb,
5252 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5253 global_operating_class)
5254 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305255 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5256 goto nla_put_failure;
5257 }
5258
5259 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305260 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305261 return (0);
5262
5263nla_put_failure:
5264 kfree_skb(skb);
5265 return -EINVAL;
5266}
5267
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305268static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305269 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305270 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305271 int data_len)
5272{
5273 u8 peer[6] = {0};
5274 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305275 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5276 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5277 eHalStatus status;
5278 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305279 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305280 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305281
5282 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305283
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305284 if (!dev) {
5285 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5286 return -EINVAL;
5287 }
5288
5289 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5290 if (!pAdapter) {
5291 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5292 return -EINVAL;
5293 }
5294
Atul Mittal115287b2014-07-08 13:26:33 +05305295 status = wlan_hdd_validate_context(pHddCtx);
5296 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305297 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305298 return -EINVAL;
5299 }
5300 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305301 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305302 return -ENOTSUPP;
5303 }
5304 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5305 data, data_len,
5306 wlan_hdd_tdls_config_enable_policy)) {
5307 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5308 return -EINVAL;
5309 }
5310
5311 /* Parse and fetch mac address */
5312 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5313 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5314 return -EINVAL;
5315 }
5316
5317 memcpy(peer, nla_data(
5318 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5319 sizeof(peer));
5320 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5321
5322 /* Parse and fetch channel */
5323 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5324 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5325 return -EINVAL;
5326 }
5327 pReqMsg.channel = nla_get_s32(
5328 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5329 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5330
5331 /* Parse and fetch global operating class */
5332 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5333 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5334 return -EINVAL;
5335 }
5336 pReqMsg.global_operating_class = nla_get_s32(
5337 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5338 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5339 pReqMsg.global_operating_class);
5340
5341 /* Parse and fetch latency ms */
5342 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5343 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5344 return -EINVAL;
5345 }
5346 pReqMsg.max_latency_ms = nla_get_s32(
5347 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5348 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5349 pReqMsg.max_latency_ms);
5350
5351 /* Parse and fetch required bandwidth kbps */
5352 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5353 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5354 return -EINVAL;
5355 }
5356
5357 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5358 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5359 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5360 pReqMsg.min_bandwidth_kbps);
5361
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305362 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305363 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305364 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305365 wlan_hdd_cfg80211_exttdls_callback);
5366
5367 EXIT();
5368 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305369}
5370
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305371static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5372 struct wireless_dev *wdev,
5373 const void *data,
5374 int data_len)
5375{
5376 int ret = 0;
5377
5378 vos_ssr_protect(__func__);
5379 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5380 vos_ssr_unprotect(__func__);
5381
5382 return ret;
5383}
5384
5385static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305386 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305387 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305388 int data_len)
5389{
5390 u8 peer[6] = {0};
5391 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305392 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5393 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5394 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305395 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305396 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305397
5398 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305399
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305400 if (!dev) {
5401 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5402 return -EINVAL;
5403 }
5404
5405 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5406 if (!pAdapter) {
5407 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5408 return -EINVAL;
5409 }
5410
Atul Mittal115287b2014-07-08 13:26:33 +05305411 status = wlan_hdd_validate_context(pHddCtx);
5412 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305413 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305414 return -EINVAL;
5415 }
5416 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305417 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305418 return -ENOTSUPP;
5419 }
5420 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5421 data, data_len,
5422 wlan_hdd_tdls_config_disable_policy)) {
5423 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5424 return -EINVAL;
5425 }
5426 /* Parse and fetch mac address */
5427 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5428 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5429 return -EINVAL;
5430 }
5431
5432 memcpy(peer, nla_data(
5433 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5434 sizeof(peer));
5435 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5436
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305437 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5438
5439 EXIT();
5440 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305441}
5442
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305443static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5444 struct wireless_dev *wdev,
5445 const void *data,
5446 int data_len)
5447{
5448 int ret = 0;
5449
5450 vos_ssr_protect(__func__);
5451 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5452 vos_ssr_unprotect(__func__);
5453
5454 return ret;
5455}
5456
Dasari Srinivas7875a302014-09-26 17:50:57 +05305457static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305458__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305459 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305460 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305461{
5462 struct net_device *dev = wdev->netdev;
5463 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5464 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5465 struct sk_buff *skb = NULL;
5466 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305467 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305468
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305469 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305470
5471 ret = wlan_hdd_validate_context(pHddCtx);
5472 if (0 != ret)
5473 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305474 return ret;
5475 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305476 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5477 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5478 fset |= WIFI_FEATURE_INFRA;
5479 }
5480
5481 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5482 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5483 fset |= WIFI_FEATURE_INFRA_5G;
5484 }
5485
5486#ifdef WLAN_FEATURE_P2P
5487 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5488 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5489 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5490 fset |= WIFI_FEATURE_P2P;
5491 }
5492#endif
5493
5494 /* Soft-AP is supported currently by default */
5495 fset |= WIFI_FEATURE_SOFT_AP;
5496
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305497 /* HOTSPOT is a supplicant feature, enable it by default */
5498 fset |= WIFI_FEATURE_HOTSPOT;
5499
Dasari Srinivas7875a302014-09-26 17:50:57 +05305500#ifdef WLAN_FEATURE_EXTSCAN
5501 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
5502 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
5503 hddLog(LOG1, FL("EXTScan is supported by firmware"));
5504 fset |= WIFI_FEATURE_EXTSCAN;
5505 }
5506#endif
5507
Dasari Srinivas7875a302014-09-26 17:50:57 +05305508 if (sme_IsFeatureSupportedByFW(NAN)) {
5509 hddLog(LOG1, FL("NAN is supported by firmware"));
5510 fset |= WIFI_FEATURE_NAN;
5511 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305512
5513 /* D2D RTT is not supported currently by default */
5514 if (sme_IsFeatureSupportedByFW(RTT)) {
5515 hddLog(LOG1, FL("RTT is supported by firmware"));
5516 fset |= WIFI_FEATURE_D2AP_RTT;
5517 }
5518
5519#ifdef FEATURE_WLAN_BATCH_SCAN
5520 if (fset & WIFI_FEATURE_EXTSCAN) {
5521 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5522 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5523 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5524 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5525 fset |= WIFI_FEATURE_BATCH_SCAN;
5526 }
5527#endif
5528
5529#ifdef FEATURE_WLAN_SCAN_PNO
5530 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5531 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5532 hddLog(LOG1, FL("PNO is supported by firmware"));
5533 fset |= WIFI_FEATURE_PNO;
5534 }
5535#endif
5536
5537 /* STA+STA is supported currently by default */
5538 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5539
5540#ifdef FEATURE_WLAN_TDLS
5541 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5542 sme_IsFeatureSupportedByFW(TDLS)) {
5543 hddLog(LOG1, FL("TDLS is supported by firmware"));
5544 fset |= WIFI_FEATURE_TDLS;
5545 }
5546
5547 /* TDLS_OFFCHANNEL is not supported currently by default */
5548#endif
5549
5550#ifdef WLAN_AP_STA_CONCURRENCY
5551 /* AP+STA concurrency is supported currently by default */
5552 fset |= WIFI_FEATURE_AP_STA;
5553#endif
5554
Mukul Sharma5add0532015-08-17 15:57:47 +05305555#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5556 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5557 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5558#endif
5559
Dasari Srinivas7875a302014-09-26 17:50:57 +05305560 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5561 NLMSG_HDRLEN);
5562
5563 if (!skb) {
5564 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5565 return -EINVAL;
5566 }
5567 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5568
5569 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5570 hddLog(LOGE, FL("nla put fail"));
5571 goto nla_put_failure;
5572 }
5573
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305574 ret = cfg80211_vendor_cmd_reply(skb);
5575 EXIT();
5576 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305577
5578nla_put_failure:
5579 kfree_skb(skb);
5580 return -EINVAL;
5581}
5582
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305583static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305584wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5585 struct wireless_dev *wdev,
5586 const void *data, int data_len)
5587{
5588 int ret = 0;
5589
5590 vos_ssr_protect(__func__);
5591 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5592 vos_ssr_unprotect(__func__);
5593
5594 return ret;
5595}
5596
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305597
5598static const struct
5599nla_policy
5600qca_wlan_vendor_wifi_logger_get_ring_data_policy
5601[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1] = {
5602 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]
5603 = {.type = NLA_U32 },
5604};
5605
5606static int
5607 __wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5608 struct wireless_dev *wdev,
5609 const void *data,
5610 int data_len)
5611{
5612 int ret;
5613 VOS_STATUS status;
5614 uint32_t ring_id;
5615 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5616 struct nlattr *tb
5617 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX + 1];
5618
5619 ENTER();
5620
5621 ret = wlan_hdd_validate_context(hdd_ctx);
5622 if (0 != ret) {
5623 return ret;
5624 }
5625
5626 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_MAX,
5627 data, data_len,
5628 qca_wlan_vendor_wifi_logger_get_ring_data_policy)) {
5629 hddLog(LOGE, FL("Invalid attribute"));
5630 return -EINVAL;
5631 }
5632
5633 /* Parse and fetch ring id */
5634 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]) {
5635 hddLog(LOGE, FL("attr ATTR failed"));
5636 return -EINVAL;
5637 }
5638
5639 ring_id = nla_get_u32(
5640 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_GET_RING_DATA_ID]);
5641
5642 hddLog(LOG1, FL("Bug report triggered by framework"));
5643
5644 status = vos_fatal_event_logs_req(WLAN_LOG_TYPE_NON_FATAL,
5645 WLAN_LOG_INDICATOR_FRAMEWORK,
5646 WLAN_LOG_REASON_CODE_FRAMEWORK,
Abhishek Singh837adf22015-10-01 17:37:37 +05305647 TRUE, TRUE
Sachin Ahujac08f72a2015-09-22 15:25:47 +05305648 );
5649 if (VOS_STATUS_SUCCESS != status) {
5650 hddLog(LOGE, FL("Failed to trigger bug report"));
5651
5652 return -EINVAL;
5653 }
5654
5655 return 0;
5656
5657
5658}
5659
5660
5661static int
5662 wlan_hdd_cfg80211_wifi_logger_get_ring_data(struct wiphy *wiphy,
5663 struct wireless_dev *wdev,
5664 const void *data,
5665 int data_len)
5666{
5667 int ret = 0;
5668
5669 vos_ssr_protect(__func__);
5670 ret = __wlan_hdd_cfg80211_wifi_logger_get_ring_data(wiphy,
5671 wdev, data, data_len);
5672 vos_ssr_unprotect(__func__);
5673
5674 return ret;
5675
5676}
5677
5678
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305679static int
5680__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305681 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305682 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305683{
5684 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5685 uint8_t i, feature_sets, max_feature_sets;
5686 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5687 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305688 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5689 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305690
5691 ENTER();
5692
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305693 ret = wlan_hdd_validate_context(pHddCtx);
5694 if (0 != ret)
5695 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305696 return ret;
5697 }
5698
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305699 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5700 data, data_len, NULL)) {
5701 hddLog(LOGE, FL("Invalid ATTR"));
5702 return -EINVAL;
5703 }
5704
5705 /* Parse and fetch max feature set */
5706 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5707 hddLog(LOGE, FL("Attr max feature set size failed"));
5708 return -EINVAL;
5709 }
5710 max_feature_sets = nla_get_u32(
5711 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5712 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5713
5714 /* Fill feature combination matrix */
5715 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305716 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5717 WIFI_FEATURE_P2P;
5718
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305719 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5720 WIFI_FEATURE_SOFT_AP;
5721
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305722 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5723 WIFI_FEATURE_SOFT_AP;
5724
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305725 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5726 WIFI_FEATURE_SOFT_AP |
5727 WIFI_FEATURE_P2P;
5728
5729 /* Add more feature combinations here */
5730
5731 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5732 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5733 hddLog(LOG1, "Feature set matrix");
5734 for (i = 0; i < feature_sets; i++)
5735 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5736
5737 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5738 sizeof(u32) * feature_sets +
5739 NLMSG_HDRLEN);
5740
5741 if (reply_skb) {
5742 if (nla_put_u32(reply_skb,
5743 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5744 feature_sets) ||
5745 nla_put(reply_skb,
5746 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5747 sizeof(u32) * feature_sets, feature_set_matrix)) {
5748 hddLog(LOGE, FL("nla put fail"));
5749 kfree_skb(reply_skb);
5750 return -EINVAL;
5751 }
5752
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305753 ret = cfg80211_vendor_cmd_reply(reply_skb);
5754 EXIT();
5755 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305756 }
5757 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5758 return -ENOMEM;
5759
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305760}
5761
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305762static int
5763wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5764 struct wireless_dev *wdev,
5765 const void *data, int data_len)
5766{
5767 int ret = 0;
5768
5769 vos_ssr_protect(__func__);
5770 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5771 data_len);
5772 vos_ssr_unprotect(__func__);
5773
5774 return ret;
5775}
5776
c_manjeecfd1efb2015-09-25 19:32:34 +05305777
5778static int
5779__wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5780 struct wireless_dev *wdev,
5781 const void *data, int data_len)
5782{
5783 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5784 int ret;
5785 ENTER();
5786
5787 ret = wlan_hdd_validate_context(pHddCtx);
5788 if (0 != ret)
5789 {
5790 return ret;
5791 }
5792
5793 if( !pHddCtx->cfg_ini->enableFwrMemDump ||
5794 (FALSE == sme_IsFeatureSupportedByFW(MEMORY_DUMP_SUPPORTED)))
5795 {
5796 hddLog(VOS_TRACE_LEVEL_INFO, FL("FW dump Logging not supported"));
5797 return -EINVAL;
5798 }
5799 /*call common API for FW mem dump req*/
5800 ret = wlan_hdd_fw_mem_dump_req(pHddCtx);
5801
5802 EXIT();
5803 return ret;
5804}
5805
5806/**
5807 * wlan_hdd_cfg80211_get_fw_mem_dump() - Get FW memory dump
5808 * @wiphy: pointer to wireless wiphy structure.
5809 * @wdev: pointer to wireless_dev structure.
5810 * @data: Pointer to the NL data.
5811 * @data_len:Length of @data
5812 *
5813 * This is called when wlan driver needs to get the firmware memory dump
5814 * via vendor specific command.
5815 *
5816 * Return: 0 on success, error number otherwise.
5817 */
5818
5819static int
5820wlan_hdd_cfg80211_get_fw_mem_dump(struct wiphy *wiphy,
5821 struct wireless_dev *wdev,
5822 const void *data, int data_len)
Sushant Kaushik8e644982015-09-23 12:18:54 +05305823{
5824 int ret = 0;
5825 vos_ssr_protect(__func__);
5826 ret = __wlan_hdd_cfg80211_get_fw_mem_dump(wiphy, wdev, data,
5827 data_len);
5828 vos_ssr_unprotect(__func__);
5829 return ret;
5830}
c_manjeecfd1efb2015-09-25 19:32:34 +05305831
Sushant Kaushik8e644982015-09-23 12:18:54 +05305832static const struct
5833nla_policy
5834qca_wlan_vendor_wifi_logger_start_policy
5835[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1] = {
5836 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]
5837 = {.type = NLA_U32 },
5838 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]
5839 = {.type = NLA_U32 },
5840 [QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]
5841 = {.type = NLA_U32 },
5842};
5843
5844/**
5845 * __wlan_hdd_cfg80211_wifi_logger_start() - This function is used to enable
5846 * or disable the collection of packet statistics from the firmware
5847 * @wiphy: WIPHY structure pointer
5848 * @wdev: Wireless device structure pointer
5849 * @data: Pointer to the data received
5850 * @data_len: Length of the data received
5851 *
5852 * This function is used to enable or disable the collection of packet
5853 * statistics from the firmware
5854 *
5855 * Return: 0 on success and errno on failure
5856 */
5857static int __wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5858 struct wireless_dev *wdev,
5859 const void *data,
5860 int data_len)
5861{
5862 eHalStatus status;
5863 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5864 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX + 1];
5865 tAniWifiStartLog start_log;
5866
5867 status = wlan_hdd_validate_context(hdd_ctx);
5868 if (0 != status) {
5869 return -EINVAL;
5870 }
5871
5872 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_START_MAX,
5873 data, data_len,
5874 qca_wlan_vendor_wifi_logger_start_policy)) {
5875 hddLog(LOGE, FL("Invalid attribute"));
5876 return -EINVAL;
5877 }
5878
5879 /* Parse and fetch ring id */
5880 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]) {
5881 hddLog(LOGE, FL("attr ATTR failed"));
5882 return -EINVAL;
5883 }
5884 start_log.ringId = nla_get_u32(
5885 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_RING_ID]);
5886 hddLog(LOG1, FL("Ring ID=%d"), start_log.ringId);
5887
5888 /* Parse and fetch verbose level */
5889 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]) {
5890 hddLog(LOGE, FL("attr verbose_level failed"));
5891 return -EINVAL;
5892 }
5893 start_log.verboseLevel = nla_get_u32(
5894 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_VERBOSE_LEVEL]);
5895 hddLog(LOG1, FL("verbose_level=%d"), start_log.verboseLevel);
5896
5897 /* Parse and fetch flag */
5898 if (!tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]) {
5899 hddLog(LOGE, FL("attr flag failed"));
5900 return -EINVAL;
5901 }
5902 start_log.flag = nla_get_u32(
5903 tb[QCA_WLAN_VENDOR_ATTR_WIFI_LOGGER_FLAGS]);
5904 hddLog(LOG1, FL("flag=%d"), start_log.flag);
5905
5906 if ((RING_ID_PER_PACKET_STATS == start_log.ringId) &&
Sushant Kaushik33200572015-08-05 16:46:20 +05305907 (!hdd_ctx->cfg_ini->wlanPerPktStatsLogEnable ||
5908 !vos_isPktStatsEnabled()))
5909
Sushant Kaushik8e644982015-09-23 12:18:54 +05305910 {
5911 hddLog(LOGE, FL("per pkt stats not enabled"));
5912 return -EINVAL;
5913 }
Sushant Kaushik8e644982015-09-23 12:18:54 +05305914
Sushant Kaushik33200572015-08-05 16:46:20 +05305915 vos_set_ring_log_level(start_log.ringId, start_log.verboseLevel);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305916 return 0;
5917}
5918
5919/**
5920 * wlan_hdd_cfg80211_wifi_logger_start() - Wrapper function used to enable
5921 * or disable the collection of packet statistics from the firmware
5922 * @wiphy: WIPHY structure pointer
5923 * @wdev: Wireless device structure pointer
5924 * @data: Pointer to the data received
5925 * @data_len: Length of the data received
5926 *
5927 * This function is used to enable or disable the collection of packet
5928 * statistics from the firmware
5929 *
5930 * Return: 0 on success and errno on failure
5931 */
5932static int wlan_hdd_cfg80211_wifi_logger_start(struct wiphy *wiphy,
5933 struct wireless_dev *wdev,
5934 const void *data,
5935 int data_len)
c_manjeecfd1efb2015-09-25 19:32:34 +05305936{
5937 int ret = 0;
5938
5939 vos_ssr_protect(__func__);
Sushant Kaushik8e644982015-09-23 12:18:54 +05305940
5941 ret = __wlan_hdd_cfg80211_wifi_logger_start(wiphy,
5942 wdev, data, data_len);
c_manjeecfd1efb2015-09-25 19:32:34 +05305943 vos_ssr_unprotect(__func__);
5944
5945 return ret;
c_manjeecfd1efb2015-09-25 19:32:34 +05305946}
5947
5948
Agarwal Ashish738843c2014-09-25 12:27:56 +05305949static const struct nla_policy
5950wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5951 +1] =
5952{
5953 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5954};
5955
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305956static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305957 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305958 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305959 int data_len)
5960{
5961 struct net_device *dev = wdev->netdev;
5962 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5963 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5964 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5965 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5966 eHalStatus status;
5967 u32 dfsFlag = 0;
5968
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305969 ENTER();
5970
Agarwal Ashish738843c2014-09-25 12:27:56 +05305971 status = wlan_hdd_validate_context(pHddCtx);
5972 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305973 return -EINVAL;
5974 }
5975 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5976 data, data_len,
5977 wlan_hdd_set_no_dfs_flag_config_policy)) {
5978 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5979 return -EINVAL;
5980 }
5981
5982 /* Parse and fetch required bandwidth kbps */
5983 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5984 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5985 return -EINVAL;
5986 }
5987
5988 dfsFlag = nla_get_u32(
5989 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5990 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5991 dfsFlag);
5992
5993 pHddCtx->disable_dfs_flag = dfsFlag;
5994
5995 sme_disable_dfs_channel(hHal, dfsFlag);
5996 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305997
5998 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305999 return 0;
6000}
Atul Mittal115287b2014-07-08 13:26:33 +05306001
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306002static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
6003 struct wireless_dev *wdev,
6004 const void *data,
6005 int data_len)
6006{
6007 int ret = 0;
6008
6009 vos_ssr_protect(__func__);
6010 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
6011 vos_ssr_unprotect(__func__);
6012
6013 return ret;
6014
6015}
6016
Mukul Sharma2a271632014-10-13 14:59:01 +05306017const struct
6018nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
6019{
6020 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
6021 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
6022};
6023
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306024static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05306025 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05306026{
6027
6028 u8 bssid[6] = {0};
6029 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6030 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6031 eHalStatus status = eHAL_STATUS_SUCCESS;
6032 v_U32_t isFwrRoamEnabled = FALSE;
6033 int ret;
6034
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306035 ENTER();
6036
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306037 ret = wlan_hdd_validate_context(pHddCtx);
6038 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306039 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05306040 }
6041
6042 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
6043 data, data_len,
6044 qca_wlan_vendor_attr);
6045 if (ret){
6046 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
6047 return -EINVAL;
6048 }
6049
6050 /* Parse and fetch Enable flag */
6051 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
6052 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
6053 return -EINVAL;
6054 }
6055
6056 isFwrRoamEnabled = nla_get_u32(
6057 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
6058
6059 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
6060
6061 /* Parse and fetch bssid */
6062 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
6063 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
6064 return -EINVAL;
6065 }
6066
6067 memcpy(bssid, nla_data(
6068 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6069 sizeof(bssid));
6070 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6071
6072 //Update roaming
6073 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306074 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05306075 return status;
6076}
6077
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306078static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6079 struct wireless_dev *wdev, const void *data, int data_len)
6080{
6081 int ret = 0;
6082
6083 vos_ssr_protect(__func__);
6084 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6085 vos_ssr_unprotect(__func__);
6086
6087 return ret;
6088}
6089
Sushant Kaushik847890c2015-09-28 16:05:17 +05306090static const struct
6091nla_policy
6092qca_wlan_vendor_get_wifi_info_policy[
6093 QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX +1] = {
6094 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION] = {.type = NLA_U8 },
6095 [QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION] = {.type = NLA_U8 },
6096};
6097
6098
6099/**
6100 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6101 * @wiphy: pointer to wireless wiphy structure.
6102 * @wdev: pointer to wireless_dev structure.
6103 * @data: Pointer to the data to be passed via vendor interface
6104 * @data_len:Length of the data to be passed
6105 *
6106 * This is called when wlan driver needs to send wifi driver related info
6107 * (driver/fw version) to the user space application upon request.
6108 *
6109 * Return: Return the Success or Failure code.
6110 */
6111static int __wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6112 struct wireless_dev *wdev,
6113 const void *data, int data_len)
6114{
6115 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6116 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX + 1];
6117 tSirVersionString version;
6118 uint32 version_len;
6119 uint8 attr;
6120 int status;
6121 struct sk_buff *reply_skb = NULL;
6122
6123 if (VOS_FTM_MODE == hdd_get_conparam()) {
6124 hddLog(LOGE, FL("Command not allowed in FTM mode"));
6125 return -EINVAL;
6126 }
6127
6128 status = wlan_hdd_validate_context(hdd_ctx);
6129 if (0 != status) {
6130 hddLog(LOGE, FL("HDD context is not valid"));
6131 return -EINVAL;
6132 }
6133
6134 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_WIFI_INFO_GET_MAX, data,
6135 data_len, qca_wlan_vendor_get_wifi_info_policy)) {
6136 hddLog(LOGE, FL("WIFI_INFO_GET NL CMD parsing failed"));
6137 return -EINVAL;
6138 }
6139
6140 if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION]) {
6141 hddLog(LOG1, FL("Rcvd req for Driver version Driver version is %s"),
6142 QWLAN_VERSIONSTR);
6143 strlcpy(version, QWLAN_VERSIONSTR, sizeof(version));
6144 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_DRIVER_VERSION;
6145 } else if (tb_vendor[QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION]) {
6146 hddLog(LOG1, FL("Rcvd req for FW version FW version is %s"),
6147 hdd_ctx->fw_Version);
6148 strlcpy(version, hdd_ctx->fw_Version, sizeof(version));
6149 attr = QCA_WLAN_VENDOR_ATTR_WIFI_INFO_FIRMWARE_VERSION;
6150 } else {
6151 hddLog(LOGE, FL("Invalid attribute in get wifi info request"));
6152 return -EINVAL;
6153 }
6154
6155 version_len = strlen(version);
6156 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
6157 version_len + NLA_HDRLEN + NLMSG_HDRLEN);
6158 if (!reply_skb) {
6159 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
6160 return -ENOMEM;
6161 }
6162
6163 if (nla_put(reply_skb, attr, version_len, version)) {
6164 hddLog(LOGE, FL("nla put fail"));
6165 kfree_skb(reply_skb);
6166 return -EINVAL;
6167 }
6168
6169 return cfg80211_vendor_cmd_reply(reply_skb);
6170}
6171
6172/**
6173 * __wlan_hdd_cfg80211_get_wifi_info() - Get the wifi driver related info
6174 * @wiphy: pointer to wireless wiphy structure.
6175 * @wdev: pointer to wireless_dev structure.
6176 * @data: Pointer to the data to be passed via vendor interface
6177 * @data_len:Length of the data to be passed
6178 * @data_len: Length of the data received
6179 *
6180 * This function is used to enable or disable the collection of packet
6181 * statistics from the firmware
6182 *
6183 * Return: 0 on success and errno on failure
6184 */
6185
6186static int
6187wlan_hdd_cfg80211_get_wifi_info(struct wiphy *wiphy,
6188 struct wireless_dev *wdev,
6189 const void *data, int data_len)
6190
6191
6192{
6193 int ret = 0;
6194
6195 vos_ssr_protect(__func__);
6196 ret = __wlan_hdd_cfg80211_get_wifi_info(wiphy,
6197 wdev, data, data_len);
6198 vos_ssr_unprotect(__func__);
6199
6200 return ret;
6201}
6202
6203
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306204/**
6205 * __wlan_hdd_cfg80211_setband() - set band
6206 * @wiphy: Pointer to wireless phy
6207 * @wdev: Pointer to wireless device
6208 * @data: Pointer to data
6209 * @data_len: Data length
6210 *
6211 * Return: 0 on success, negative errno on failure
6212 */
6213static int
6214__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6215 struct wireless_dev *wdev,
6216 const void *data,
6217 int data_len)
6218{
6219 struct net_device *dev = wdev->netdev;
6220 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6221 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6222 int ret;
6223 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6224 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6225
6226 ENTER();
6227
6228 ret = wlan_hdd_validate_context(hdd_ctx);
6229 if (0 != ret) {
6230 hddLog(LOGE, FL("HDD context is not valid"));
6231 return ret;
6232 }
6233
6234 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6235 policy)) {
6236 hddLog(LOGE, FL("Invalid ATTR"));
6237 return -EINVAL;
6238 }
6239
6240 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6241 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6242 return -EINVAL;
6243 }
6244
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306245 hdd_ctx->isSetBandByNL = TRUE;
6246 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306247 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306248 hdd_ctx->isSetBandByNL = FALSE;
6249
6250 EXIT();
6251 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306252}
6253
6254/**
6255 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6256 * @wiphy: wiphy structure pointer
6257 * @wdev: Wireless device structure pointer
6258 * @data: Pointer to the data received
6259 * @data_len: Length of @data
6260 *
6261 * Return: 0 on success; errno on failure
6262 */
6263static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6264 struct wireless_dev *wdev,
6265 const void *data,
6266 int data_len)
6267{
6268 int ret = 0;
6269
6270 vos_ssr_protect(__func__);
6271 ret = __wlan_hdd_cfg80211_setband(wiphy,
6272 wdev, data, data_len);
6273 vos_ssr_unprotect(__func__);
6274
6275 return ret;
6276}
6277
Sunil Duttc69bccb2014-05-26 21:30:20 +05306278const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
6279{
Mukul Sharma2a271632014-10-13 14:59:01 +05306280 {
6281 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6282 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
6283 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6284 WIPHY_VENDOR_CMD_NEED_NETDEV |
6285 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306286 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05306287 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05306288
6289 {
6290 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6291 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
6292 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6293 WIPHY_VENDOR_CMD_NEED_NETDEV |
6294 WIPHY_VENDOR_CMD_NEED_RUNNING,
6295 .doit = wlan_hdd_cfg80211_nan_request
6296 },
6297
Sunil Duttc69bccb2014-05-26 21:30:20 +05306298#ifdef WLAN_FEATURE_LINK_LAYER_STATS
6299 {
6300 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6301 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
6302 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6303 WIPHY_VENDOR_CMD_NEED_NETDEV |
6304 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306305 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05306306 },
6307
6308 {
6309 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6310 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
6311 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6312 WIPHY_VENDOR_CMD_NEED_NETDEV |
6313 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306314 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05306315 },
6316
6317 {
6318 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6319 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
6320 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6321 WIPHY_VENDOR_CMD_NEED_NETDEV |
6322 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306323 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05306324 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05306325#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05306326#ifdef WLAN_FEATURE_EXTSCAN
6327 {
6328 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6329 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
6330 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6331 WIPHY_VENDOR_CMD_NEED_NETDEV |
6332 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306333 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05306334 },
6335 {
6336 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6337 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
6338 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6339 WIPHY_VENDOR_CMD_NEED_NETDEV |
6340 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306341 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05306342 },
6343 {
6344 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6345 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
6346 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6347 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306348 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05306349 },
6350 {
6351 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6352 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
6353 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6354 WIPHY_VENDOR_CMD_NEED_NETDEV |
6355 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306356 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05306357 },
6358 {
6359 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6360 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
6361 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6362 WIPHY_VENDOR_CMD_NEED_NETDEV |
6363 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306364 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05306365 },
6366 {
6367 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6368 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
6369 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6370 WIPHY_VENDOR_CMD_NEED_NETDEV |
6371 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306372 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05306373 },
6374 {
6375 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6376 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
6377 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6378 WIPHY_VENDOR_CMD_NEED_NETDEV |
6379 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306380 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05306381 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05306382 {
6383 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6384 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
6385 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6386 WIPHY_VENDOR_CMD_NEED_NETDEV |
6387 WIPHY_VENDOR_CMD_NEED_RUNNING,
6388 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
6389 },
6390 {
6391 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6392 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
6393 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6394 WIPHY_VENDOR_CMD_NEED_NETDEV |
6395 WIPHY_VENDOR_CMD_NEED_RUNNING,
6396 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
6397 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05306398#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05306399/*EXT TDLS*/
6400 {
6401 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6402 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
6403 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6404 WIPHY_VENDOR_CMD_NEED_NETDEV |
6405 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306406 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05306407 },
6408 {
6409 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6410 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
6411 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6412 WIPHY_VENDOR_CMD_NEED_NETDEV |
6413 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306414 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05306415 },
6416 {
6417 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6418 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
6419 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6420 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306421 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05306422 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05306423 {
6424 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6425 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
6426 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6427 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306428 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05306429 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05306430 {
6431 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6432 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
6433 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6434 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306435 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05306436 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05306437 {
6438 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6439 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
6440 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6441 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306442 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05306443 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306444 {
6445 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6446 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
6447 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6448 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306449 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306450 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306451 {
6452 .info.vendor_id = QCA_NL80211_VENDOR_ID,
c_manjeecfd1efb2015-09-25 19:32:34 +05306453 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP,
6454 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6455 WIPHY_VENDOR_CMD_NEED_NETDEV |
6456 WIPHY_VENDOR_CMD_NEED_RUNNING,
6457 .doit = wlan_hdd_cfg80211_get_fw_mem_dump
6458 },
6459 {
6460 .info.vendor_id = QCA_NL80211_VENDOR_ID,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306461 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
6462 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6463 WIPHY_VENDOR_CMD_NEED_NETDEV |
6464 WIPHY_VENDOR_CMD_NEED_RUNNING,
6465 .doit = wlan_hdd_cfg80211_setband
Sushant Kaushik8e644982015-09-23 12:18:54 +05306466 },
6467 {
6468 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6469 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_START,
6470 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6471 WIPHY_VENDOR_CMD_NEED_NETDEV,
6472 .doit = wlan_hdd_cfg80211_wifi_logger_start
6473 },
Sushant Kaushik847890c2015-09-28 16:05:17 +05306474 {
6475 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6476 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
6477 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6478 WIPHY_VENDOR_CMD_NEED_NETDEV|
6479 WIPHY_VENDOR_CMD_NEED_RUNNING,
6480 .doit = wlan_hdd_cfg80211_get_wifi_info
Sachin Ahujac08f72a2015-09-22 15:25:47 +05306481 },
6482 {
6483 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6484 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_RING_DATA,
6485 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6486 WIPHY_VENDOR_CMD_NEED_NETDEV |
6487 WIPHY_VENDOR_CMD_NEED_RUNNING,
6488 .doit = wlan_hdd_cfg80211_wifi_logger_get_ring_data
Sushant Kaushik847890c2015-09-28 16:05:17 +05306489 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05306490};
6491
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006492/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05306493static const
6494struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006495{
6496#ifdef FEATURE_WLAN_CH_AVOID
6497 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05306498 .vendor_id = QCA_NL80211_VENDOR_ID,
6499 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006500 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05306501#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
6502#ifdef WLAN_FEATURE_LINK_LAYER_STATS
6503 {
6504 /* Index = 1*/
6505 .vendor_id = QCA_NL80211_VENDOR_ID,
6506 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
6507 },
6508 {
6509 /* Index = 2*/
6510 .vendor_id = QCA_NL80211_VENDOR_ID,
6511 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
6512 },
6513 {
6514 /* Index = 3*/
6515 .vendor_id = QCA_NL80211_VENDOR_ID,
6516 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
6517 },
6518 {
6519 /* Index = 4*/
6520 .vendor_id = QCA_NL80211_VENDOR_ID,
6521 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
6522 },
6523 {
6524 /* Index = 5*/
6525 .vendor_id = QCA_NL80211_VENDOR_ID,
6526 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
6527 },
6528 {
6529 /* Index = 6*/
6530 .vendor_id = QCA_NL80211_VENDOR_ID,
6531 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
6532 },
6533#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05306534#ifdef WLAN_FEATURE_EXTSCAN
6535 {
6536 .vendor_id = QCA_NL80211_VENDOR_ID,
6537 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
6538 },
6539 {
6540 .vendor_id = QCA_NL80211_VENDOR_ID,
6541 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
6542 },
6543 {
6544 .vendor_id = QCA_NL80211_VENDOR_ID,
6545 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
6546 },
6547 {
6548 .vendor_id = QCA_NL80211_VENDOR_ID,
6549 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
6550 },
6551 {
6552 .vendor_id = QCA_NL80211_VENDOR_ID,
6553 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
6554 },
6555 {
6556 .vendor_id = QCA_NL80211_VENDOR_ID,
6557 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
6558 },
6559 {
6560 .vendor_id = QCA_NL80211_VENDOR_ID,
6561 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
6562 },
6563 {
6564 .vendor_id = QCA_NL80211_VENDOR_ID,
6565 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
6566 },
6567 {
6568 .vendor_id = QCA_NL80211_VENDOR_ID,
6569 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
6570 },
6571 {
6572 .vendor_id = QCA_NL80211_VENDOR_ID,
6573 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
6574 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05306575 {
6576 .vendor_id = QCA_NL80211_VENDOR_ID,
6577 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
6578 },
6579 {
6580 .vendor_id = QCA_NL80211_VENDOR_ID,
6581 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
6582 },
6583 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
6584 .vendor_id = QCA_NL80211_VENDOR_ID,
6585 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
6586 },
6587 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
6588 .vendor_id = QCA_NL80211_VENDOR_ID,
6589 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
6590 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05306591#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05306592/*EXT TDLS*/
6593 {
6594 .vendor_id = QCA_NL80211_VENDOR_ID,
6595 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
6596 },
c_manjeecfd1efb2015-09-25 19:32:34 +05306597 [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = {
6598 .vendor_id = QCA_NL80211_VENDOR_ID,
6599 .subcmd = QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP
6600 },
6601
Srinivas Dasari030bad32015-02-18 23:23:54 +05306602
6603 {
6604 .vendor_id = QCA_NL80211_VENDOR_ID,
6605 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
6606 },
6607
Sushant Kaushik084f6592015-09-10 13:11:56 +05306608 {
6609 .vendor_id = QCA_NL80211_VENDOR_ID,
6610 .subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_WIFI_INFO,
6611 }
6612
6613
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006614};
6615
Jeff Johnson295189b2012-06-20 16:38:30 -07006616/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306617 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306618 * This function is called by hdd_wlan_startup()
6619 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306620 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07006621 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306622struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07006623{
6624 struct wiphy *wiphy;
6625 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306626 /*
6627 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07006628 */
6629 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
6630
6631 if (!wiphy)
6632 {
6633 /* Print error and jump into err label and free the memory */
6634 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
6635 return NULL;
6636 }
6637
Sunil Duttc69bccb2014-05-26 21:30:20 +05306638
Jeff Johnson295189b2012-06-20 16:38:30 -07006639 return wiphy;
6640}
6641
6642/*
6643 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306644 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07006645 * private ioctl to change the band value
6646 */
6647int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
6648{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306649 int i, j;
6650 eNVChannelEnabledType channelEnabledState;
6651
Jeff Johnsone7245742012-09-05 17:12:55 -07006652 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306653
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306654 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006655 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306656
6657 if (NULL == wiphy->bands[i])
6658 {
6659 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
6660 __func__, i);
6661 continue;
6662 }
6663
6664 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
6665 {
6666 struct ieee80211_supported_band *band = wiphy->bands[i];
6667
6668 channelEnabledState = vos_nv_getChannelEnabledState(
6669 band->channels[j].hw_value);
6670
6671 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
6672 {
Abhishek Singh678227a2014-11-04 10:52:38 +05306673 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306674 continue;
6675 }
6676 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
6677 {
6678 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6679 continue;
6680 }
6681
6682 if (NV_CHANNEL_DISABLE == channelEnabledState ||
6683 NV_CHANNEL_INVALID == channelEnabledState)
6684 {
6685 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6686 }
6687 else if (NV_CHANNEL_DFS == channelEnabledState)
6688 {
6689 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
6690 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
6691 }
6692 else
6693 {
6694 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
6695 |IEEE80211_CHAN_RADAR);
6696 }
6697 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006698 }
6699 return 0;
6700}
6701/*
6702 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306703 * This function is called by hdd_wlan_startup()
6704 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07006705 * This function is used to initialize and register wiphy structure.
6706 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306707int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07006708 struct wiphy *wiphy,
6709 hdd_config_t *pCfg
6710 )
6711{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306712 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05306713 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6714
Jeff Johnsone7245742012-09-05 17:12:55 -07006715 ENTER();
6716
Jeff Johnson295189b2012-06-20 16:38:30 -07006717 /* Now bind the underlying wlan device with wiphy */
6718 set_wiphy_dev(wiphy, dev);
6719
6720 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07006721
Kiet Lam6c583332013-10-14 05:37:09 +05306722#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07006723 /* the flag for the other case would be initialzed in
6724 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07006725 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05306726#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07006727
Amar Singhalfddc28c2013-09-05 13:03:40 -07006728 /* This will disable updating of NL channels from passive to
6729 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306730#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
6731 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
6732#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07006733 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306734#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07006735
Amar Singhala49cbc52013-10-08 18:37:44 -07006736
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006737#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07006738 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
6739 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
6740 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07006741 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306742#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
6743 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
6744#else
6745 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
6746#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006747#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07006748
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006749#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006750 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08006751#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006752 || pCfg->isFastRoamIniFeatureEnabled
6753#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006754#ifdef FEATURE_WLAN_ESE
6755 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006756#endif
6757 )
6758 {
6759 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
6760 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08006761#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006762#ifdef FEATURE_WLAN_TDLS
6763 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
6764 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
6765#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05306766#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05306767 if (pCfg->configPNOScanSupport)
6768 {
6769 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
6770 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
6771 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
6772 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
6773 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05306774#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006775
Abhishek Singh10d85972015-04-17 10:27:23 +05306776#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6777 wiphy->features |= NL80211_FEATURE_HT_IBSS;
6778#endif
6779
Amar Singhalfddc28c2013-09-05 13:03:40 -07006780#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07006781 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
6782 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07006783 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07006784 driver need to determine what to do with both
6785 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07006786
6787 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07006788#else
6789 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07006790#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006791
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306792 wiphy->max_scan_ssids = MAX_SCAN_SSID;
6793
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05306794 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07006795
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306796 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
6797
Jeff Johnson295189b2012-06-20 16:38:30 -07006798 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05306799 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
6800 | BIT(NL80211_IFTYPE_ADHOC)
6801 | BIT(NL80211_IFTYPE_P2P_CLIENT)
6802 | BIT(NL80211_IFTYPE_P2P_GO)
6803 | BIT(NL80211_IFTYPE_AP);
6804
6805 if (VOS_MONITOR_MODE == hdd_get_conparam())
6806 {
6807 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
6808 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006809
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306810 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006811 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306812#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6813 if( pCfg->enableMCC )
6814 {
6815 /* Currently, supports up to two channels */
6816 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006817
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306818 if( !pCfg->allowMCCGODiffBI )
6819 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006820
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306821 }
6822 wiphy->iface_combinations = &wlan_hdd_iface_combination;
6823 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006824#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306825 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006826
Jeff Johnson295189b2012-06-20 16:38:30 -07006827 /* Before registering we need to update the ht capabilitied based
6828 * on ini values*/
6829 if( !pCfg->ShortGI20MhzEnable )
6830 {
6831 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6832 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6833 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6834 }
6835
6836 if( !pCfg->ShortGI40MhzEnable )
6837 {
6838 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
6839 }
6840
6841 if( !pCfg->nChannelBondingMode5GHz )
6842 {
6843 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6844 }
6845
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306846 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05306847 if (true == hdd_is_5g_supported(pHddCtx))
6848 {
6849 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
6850 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306851
6852 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
6853 {
6854
6855 if (NULL == wiphy->bands[i])
6856 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05306857 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306858 __func__, i);
6859 continue;
6860 }
6861
6862 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
6863 {
6864 struct ieee80211_supported_band *band = wiphy->bands[i];
6865
6866 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
6867 {
6868 // Enable social channels for P2P
6869 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
6870 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
6871 else
6872 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6873 continue;
6874 }
6875 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
6876 {
6877 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6878 continue;
6879 }
6880 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006881 }
6882 /*Initialise the supported cipher suite details*/
6883 wiphy->cipher_suites = hdd_cipher_suites;
6884 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
6885
6886 /*signal strength in mBm (100*dBm) */
6887 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
6888
6889#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05306890 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07006891#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006892
Sunil Duttc69bccb2014-05-26 21:30:20 +05306893 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
6894 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006895 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
6896 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
6897
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306898 EXIT();
6899 return 0;
6900}
6901
6902/* In this function we are registering wiphy. */
6903int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
6904{
6905 ENTER();
6906 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006907 if (0 > wiphy_register(wiphy))
6908 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306909 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07006910 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
6911 return -EIO;
6912 }
6913
6914 EXIT();
6915 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306916}
Jeff Johnson295189b2012-06-20 16:38:30 -07006917
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306918/* In this function we are updating channel list when,
6919 regulatory domain is FCC and country code is US.
6920 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
6921 As per FCC smart phone is not a indoor device.
6922 GO should not opeate on indoor channels */
6923void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
6924{
6925 int j;
6926 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6927 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
6928 //Default counrtycode from NV at the time of wiphy initialization.
6929 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
6930 &defaultCountryCode[0]))
6931 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006932 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306933 }
6934 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
6935 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306936 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
6937 {
6938 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
6939 return;
6940 }
6941 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
6942 {
6943 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
6944 // Mark UNII -1 band channel as passive
6945 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
6946 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
6947 }
6948 }
6949}
6950
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306951/* This function registers for all frame which supplicant is interested in */
6952void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006953{
Jeff Johnson295189b2012-06-20 16:38:30 -07006954 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6955 /* Register for all P2P action, public action etc frames */
6956 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6957
Jeff Johnsone7245742012-09-05 17:12:55 -07006958 ENTER();
6959
Jeff Johnson295189b2012-06-20 16:38:30 -07006960 /* Right now we are registering these frame when driver is getting
6961 initialized. Once we will move to 2.6.37 kernel, in which we have
6962 frame register ops, we will move this code as a part of that */
6963 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306964 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006965 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6966
6967 /* GAS Initial Response */
6968 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6969 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306970
Jeff Johnson295189b2012-06-20 16:38:30 -07006971 /* GAS Comeback Request */
6972 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6973 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6974
6975 /* GAS Comeback Response */
6976 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6977 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6978
6979 /* P2P Public Action */
6980 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306981 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006982 P2P_PUBLIC_ACTION_FRAME_SIZE );
6983
6984 /* P2P Action */
6985 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6986 (v_U8_t*)P2P_ACTION_FRAME,
6987 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07006988
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05306989 /* WNM BSS Transition Request frame */
6990 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6991 (v_U8_t*)WNM_BSS_ACTION_FRAME,
6992 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006993
6994 /* WNM-Notification */
6995 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6996 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6997 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006998}
6999
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05307000void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07007001{
Jeff Johnson295189b2012-06-20 16:38:30 -07007002 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
7003 /* Register for all P2P action, public action etc frames */
7004 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
7005
Jeff Johnsone7245742012-09-05 17:12:55 -07007006 ENTER();
7007
Jeff Johnson295189b2012-06-20 16:38:30 -07007008 /* Right now we are registering these frame when driver is getting
7009 initialized. Once we will move to 2.6.37 kernel, in which we have
7010 frame register ops, we will move this code as a part of that */
7011 /* GAS Initial Request */
7012
7013 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
7014 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
7015
7016 /* GAS Initial Response */
7017 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
7018 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307019
Jeff Johnson295189b2012-06-20 16:38:30 -07007020 /* GAS Comeback Request */
7021 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
7022 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
7023
7024 /* GAS Comeback Response */
7025 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
7026 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
7027
7028 /* P2P Public Action */
7029 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307030 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07007031 P2P_PUBLIC_ACTION_FRAME_SIZE );
7032
7033 /* P2P Action */
7034 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
7035 (v_U8_t*)P2P_ACTION_FRAME,
7036 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07007037 /* WNM-Notification */
7038 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
7039 (v_U8_t*)WNM_NOTIFICATION_FRAME,
7040 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07007041}
7042
7043#ifdef FEATURE_WLAN_WAPI
7044void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05307045 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07007046{
7047 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7048 tCsrRoamSetKey setKey;
7049 v_BOOL_t isConnected = TRUE;
7050 int status = 0;
7051 v_U32_t roamId= 0xFF;
7052 tANI_U8 *pKeyPtr = NULL;
7053 int n = 0;
7054
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307055 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
7056 __func__, hdd_device_modetoString(pAdapter->device_mode),
7057 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007058
Gopichand Nakkalae7480202013-02-11 15:24:22 +05307059 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07007060 setKey.keyId = key_index; // Store Key ID
7061 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
7062 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
7063 setKey.paeRole = 0 ; // the PAE role
7064 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
7065 {
7066 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
7067 }
7068 else
7069 {
7070 isConnected = hdd_connIsConnected(pHddStaCtx);
7071 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
7072 }
7073 setKey.keyLength = key_Len;
7074 pKeyPtr = setKey.Key;
7075 memcpy( pKeyPtr, key, key_Len);
7076
Arif Hussain6d2a3322013-11-17 19:50:10 -08007077 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07007078 __func__, key_Len);
7079 for (n = 0 ; n < key_Len; n++)
7080 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
7081 __func__,n,setKey.Key[n]);
7082
7083 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
7084 if ( isConnected )
7085 {
7086 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
7087 pAdapter->sessionId, &setKey, &roamId );
7088 }
7089 if ( status != 0 )
7090 {
7091 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7092 "[%4d] sme_RoamSetKey returned ERROR status= %d",
7093 __LINE__, status );
7094 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
7095 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05307096 /* Need to clear any trace of key value in the memory.
7097 * Thus zero out the memory even though it is local
7098 * variable.
7099 */
7100 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07007101}
7102#endif /* FEATURE_WLAN_WAPI*/
7103
7104#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307105int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07007106 beacon_data_t **ppBeacon,
7107 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007108#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307109int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007110 beacon_data_t **ppBeacon,
7111 struct cfg80211_beacon_data *params,
7112 int dtim_period)
7113#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307114{
Jeff Johnson295189b2012-06-20 16:38:30 -07007115 int size;
7116 beacon_data_t *beacon = NULL;
7117 beacon_data_t *old = NULL;
7118 int head_len,tail_len;
7119
Jeff Johnsone7245742012-09-05 17:12:55 -07007120 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07007121 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307122 {
7123 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7124 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007125 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307126 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007127
7128 old = pAdapter->sessionCtx.ap.beacon;
7129
7130 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307131 {
7132 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7133 FL("session(%d) old and new heads points to NULL"),
7134 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007135 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307136 }
7137
7138 if (params->tail && !params->tail_len)
7139 {
7140 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7141 FL("tail_len is zero but tail is not NULL"));
7142 return -EINVAL;
7143 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007144
Jeff Johnson295189b2012-06-20 16:38:30 -07007145#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
7146 /* Kernel 3.0 is not updating dtim_period for set beacon */
7147 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307148 {
7149 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7150 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007151 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307152 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007153#endif
7154
7155 if(params->head)
7156 head_len = params->head_len;
7157 else
7158 head_len = old->head_len;
7159
7160 if(params->tail || !old)
7161 tail_len = params->tail_len;
7162 else
7163 tail_len = old->tail_len;
7164
7165 size = sizeof(beacon_data_t) + head_len + tail_len;
7166
7167 beacon = kzalloc(size, GFP_KERNEL);
7168
7169 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307170 {
7171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7172 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007173 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307174 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007175
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007176#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007177 if(params->dtim_period || !old )
7178 beacon->dtim_period = params->dtim_period;
7179 else
7180 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007181#else
7182 if(dtim_period || !old )
7183 beacon->dtim_period = dtim_period;
7184 else
7185 beacon->dtim_period = old->dtim_period;
7186#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307187
Jeff Johnson295189b2012-06-20 16:38:30 -07007188 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
7189 beacon->tail = beacon->head + head_len;
7190 beacon->head_len = head_len;
7191 beacon->tail_len = tail_len;
7192
7193 if(params->head) {
7194 memcpy (beacon->head,params->head,beacon->head_len);
7195 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307196 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07007197 if(old)
7198 memcpy (beacon->head,old->head,beacon->head_len);
7199 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307200
Jeff Johnson295189b2012-06-20 16:38:30 -07007201 if(params->tail) {
7202 memcpy (beacon->tail,params->tail,beacon->tail_len);
7203 }
7204 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307205 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07007206 memcpy (beacon->tail,old->tail,beacon->tail_len);
7207 }
7208
7209 *ppBeacon = beacon;
7210
7211 kfree(old);
7212
7213 return 0;
7214
7215}
Jeff Johnson295189b2012-06-20 16:38:30 -07007216
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05307217v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
7218#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
7219 const v_U8_t *pIes,
7220#else
7221 v_U8_t *pIes,
7222#endif
7223 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007224{
7225 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05307226 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07007227 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307228
Jeff Johnson295189b2012-06-20 16:38:30 -07007229 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307230 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007231 elem_id = ptr[0];
7232 elem_len = ptr[1];
7233 left -= 2;
7234 if(elem_len > left)
7235 {
7236 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007237 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007238 eid,elem_len,left);
7239 return NULL;
7240 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307241 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007242 {
7243 return ptr;
7244 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307245
Jeff Johnson295189b2012-06-20 16:38:30 -07007246 left -= elem_len;
7247 ptr += (elem_len + 2);
7248 }
7249 return NULL;
7250}
7251
Jeff Johnson295189b2012-06-20 16:38:30 -07007252/* Check if rate is 11g rate or not */
7253static int wlan_hdd_rate_is_11g(u8 rate)
7254{
Sanjay Devnani28322e22013-06-21 16:13:40 -07007255 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07007256 u8 i;
7257 for (i = 0; i < 8; i++)
7258 {
7259 if(rate == gRateArray[i])
7260 return TRUE;
7261 }
7262 return FALSE;
7263}
7264
7265/* Check for 11g rate and set proper 11g only mode */
7266static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
7267 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
7268{
7269 u8 i, num_rates = pIe[0];
7270
7271 pIe += 1;
7272 for ( i = 0; i < num_rates; i++)
7273 {
7274 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
7275 {
7276 /* If rate set have 11g rate than change the mode to 11G */
7277 *pSapHw_mode = eSAP_DOT11_MODE_11g;
7278 if (pIe[i] & BASIC_RATE_MASK)
7279 {
7280 /* If we have 11g rate as basic rate, it means mode
7281 is 11g only mode.
7282 */
7283 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
7284 *pCheckRatesfor11g = FALSE;
7285 }
7286 }
7287 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
7288 {
7289 *require_ht = TRUE;
7290 }
7291 }
7292 return;
7293}
7294
7295static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
7296{
7297 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7298 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7299 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
7300 u8 checkRatesfor11g = TRUE;
7301 u8 require_ht = FALSE;
7302 u8 *pIe=NULL;
7303
7304 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
7305
7306 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
7307 pBeacon->head_len, WLAN_EID_SUPP_RATES);
7308 if (pIe != NULL)
7309 {
7310 pIe += 1;
7311 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
7312 &pConfig->SapHw_mode);
7313 }
7314
7315 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7316 WLAN_EID_EXT_SUPP_RATES);
7317 if (pIe != NULL)
7318 {
7319
7320 pIe += 1;
7321 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
7322 &pConfig->SapHw_mode);
7323 }
7324
7325 if( pConfig->channel > 14 )
7326 {
7327 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
7328 }
7329
7330 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7331 WLAN_EID_HT_CAPABILITY);
7332
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307333 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07007334 {
7335 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
7336 if(require_ht)
7337 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
7338 }
7339}
7340
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307341static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
7342 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
7343{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07007344 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307345 v_U8_t *pIe = NULL;
7346 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7347
7348 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
7349 pBeacon->tail, pBeacon->tail_len);
7350
7351 if (pIe)
7352 {
7353 ielen = pIe[1] + 2;
7354 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
7355 {
7356 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
7357 }
7358 else
7359 {
7360 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
7361 return -EINVAL;
7362 }
7363 *total_ielen += ielen;
7364 }
7365 return 0;
7366}
7367
Arif Hussaine7f3ea52013-09-12 21:56:36 -07007368static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
7369 v_U8_t *genie, v_U8_t *total_ielen)
7370{
7371 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7372 int left = pBeacon->tail_len;
7373 v_U8_t *ptr = pBeacon->tail;
7374 v_U8_t elem_id, elem_len;
7375 v_U16_t ielen = 0;
7376
7377 if ( NULL == ptr || 0 == left )
7378 return;
7379
7380 while (left >= 2)
7381 {
7382 elem_id = ptr[0];
7383 elem_len = ptr[1];
7384 left -= 2;
7385 if (elem_len > left)
7386 {
7387 hddLog( VOS_TRACE_LEVEL_ERROR,
7388 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
7389 elem_id, elem_len, left);
7390 return;
7391 }
7392 if (IE_EID_VENDOR == elem_id)
7393 {
7394 /* skipping the VSIE's which we don't want to include or
7395 * it will be included by existing code
7396 */
7397 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
7398#ifdef WLAN_FEATURE_WFD
7399 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
7400#endif
7401 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
7402 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
7403 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
7404 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
7405 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
7406 {
7407 ielen = ptr[1] + 2;
7408 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
7409 {
7410 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
7411 *total_ielen += ielen;
7412 }
7413 else
7414 {
7415 hddLog( VOS_TRACE_LEVEL_ERROR,
7416 "IE Length is too big "
7417 "IEs eid=%d elem_len=%d total_ie_lent=%d",
7418 elem_id, elem_len, *total_ielen);
7419 }
7420 }
7421 }
7422
7423 left -= elem_len;
7424 ptr += (elem_len + 2);
7425 }
7426 return;
7427}
7428
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007429#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007430static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
7431 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007432#else
7433static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
7434 struct cfg80211_beacon_data *params)
7435#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007436{
7437 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307438 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007439 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07007440 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007441
7442 genie = vos_mem_malloc(MAX_GENIE_LEN);
7443
7444 if(genie == NULL) {
7445
7446 return -ENOMEM;
7447 }
7448
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307449 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7450 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007451 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307452 hddLog(LOGE,
7453 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307454 ret = -EINVAL;
7455 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007456 }
7457
7458#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307459 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7460 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
7461 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307462 hddLog(LOGE,
7463 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307464 ret = -EINVAL;
7465 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007466 }
7467#endif
7468
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307469 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7470 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007471 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307472 hddLog(LOGE,
7473 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307474 ret = -EINVAL;
7475 goto done;
7476 }
7477
7478 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
7479 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07007480 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07007481 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007482
7483 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7484 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
7485 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
7486 {
7487 hddLog(LOGE,
7488 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007489 ret = -EINVAL;
7490 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007491 }
7492
7493 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7494 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
7495 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7496 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7497 ==eHAL_STATUS_FAILURE)
7498 {
7499 hddLog(LOGE,
7500 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007501 ret = -EINVAL;
7502 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007503 }
7504
7505 // Added for ProResp IE
7506 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
7507 {
7508 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
7509 u8 probe_rsp_ie_len[3] = {0};
7510 u8 counter = 0;
7511 /* Check Probe Resp Length if it is greater then 255 then Store
7512 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
7513 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
7514 Store More then 255 bytes into One Variable.
7515 */
7516 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
7517 {
7518 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
7519 {
7520 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
7521 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
7522 }
7523 else
7524 {
7525 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
7526 rem_probe_resp_ie_len = 0;
7527 }
7528 }
7529
7530 rem_probe_resp_ie_len = 0;
7531
7532 if (probe_rsp_ie_len[0] > 0)
7533 {
7534 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7535 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
7536 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7537 probe_rsp_ie_len[0], NULL,
7538 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7539 {
7540 hddLog(LOGE,
7541 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007542 ret = -EINVAL;
7543 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007544 }
7545 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
7546 }
7547
7548 if (probe_rsp_ie_len[1] > 0)
7549 {
7550 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7551 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
7552 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7553 probe_rsp_ie_len[1], NULL,
7554 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7555 {
7556 hddLog(LOGE,
7557 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007558 ret = -EINVAL;
7559 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007560 }
7561 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
7562 }
7563
7564 if (probe_rsp_ie_len[2] > 0)
7565 {
7566 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7567 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
7568 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7569 probe_rsp_ie_len[2], NULL,
7570 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7571 {
7572 hddLog(LOGE,
7573 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007574 ret = -EINVAL;
7575 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007576 }
7577 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
7578 }
7579
7580 if (probe_rsp_ie_len[1] == 0 )
7581 {
7582 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7583 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7584 eANI_BOOLEAN_FALSE) )
7585 {
7586 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007587 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007588 }
7589 }
7590
7591 if (probe_rsp_ie_len[2] == 0 )
7592 {
7593 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7594 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7595 eANI_BOOLEAN_FALSE) )
7596 {
7597 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007598 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007599 }
7600 }
7601
7602 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7603 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
7604 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7605 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7606 == eHAL_STATUS_FAILURE)
7607 {
7608 hddLog(LOGE,
7609 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007610 ret = -EINVAL;
7611 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007612 }
7613 }
7614 else
7615 {
7616 // Reset WNI_CFG_PROBE_RSP Flags
7617 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
7618
7619 hddLog(VOS_TRACE_LEVEL_INFO,
7620 "%s: No Probe Response IE received in set beacon",
7621 __func__);
7622 }
7623
7624 // Added for AssocResp IE
7625 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
7626 {
7627 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7628 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
7629 params->assocresp_ies_len, NULL,
7630 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7631 {
7632 hddLog(LOGE,
7633 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007634 ret = -EINVAL;
7635 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007636 }
7637
7638 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7639 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
7640 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7641 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7642 == eHAL_STATUS_FAILURE)
7643 {
7644 hddLog(LOGE,
7645 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007646 ret = -EINVAL;
7647 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007648 }
7649 }
7650 else
7651 {
7652 hddLog(VOS_TRACE_LEVEL_INFO,
7653 "%s: No Assoc Response IE received in set beacon",
7654 __func__);
7655
7656 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7657 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7658 eANI_BOOLEAN_FALSE) )
7659 {
7660 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007661 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007662 }
7663 }
7664
Jeff Johnsone7245742012-09-05 17:12:55 -07007665done:
Jeff Johnson295189b2012-06-20 16:38:30 -07007666 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307667 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007668}
Jeff Johnson295189b2012-06-20 16:38:30 -07007669
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307670/*
Jeff Johnson295189b2012-06-20 16:38:30 -07007671 * FUNCTION: wlan_hdd_validate_operation_channel
7672 * called by wlan_hdd_cfg80211_start_bss() and
7673 * wlan_hdd_cfg80211_set_channel()
7674 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307675 * channel list.
7676 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007677VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07007678{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307679
Jeff Johnson295189b2012-06-20 16:38:30 -07007680 v_U32_t num_ch = 0;
7681 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7682 u32 indx = 0;
7683 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307684 v_U8_t fValidChannel = FALSE, count = 0;
7685 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307686
Jeff Johnson295189b2012-06-20 16:38:30 -07007687 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7688
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307689 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07007690 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307691 /* Validate the channel */
7692 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007693 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307694 if ( channel == rfChannels[count].channelNum )
7695 {
7696 fValidChannel = TRUE;
7697 break;
7698 }
7699 }
7700 if (fValidChannel != TRUE)
7701 {
7702 hddLog(VOS_TRACE_LEVEL_ERROR,
7703 "%s: Invalid Channel [%d]", __func__, channel);
7704 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007705 }
7706 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307707 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007708 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307709 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7710 valid_ch, &num_ch))
7711 {
7712 hddLog(VOS_TRACE_LEVEL_ERROR,
7713 "%s: failed to get valid channel list", __func__);
7714 return VOS_STATUS_E_FAILURE;
7715 }
7716 for (indx = 0; indx < num_ch; indx++)
7717 {
7718 if (channel == valid_ch[indx])
7719 {
7720 break;
7721 }
7722 }
7723
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05307724 if (indx >= num_ch)
7725 {
7726 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
7727 {
7728 eCsrBand band;
7729 unsigned int freq;
7730
7731 sme_GetFreqBand(hHal, &band);
7732
7733 if (eCSR_BAND_5G == band)
7734 {
7735#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
7736 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
7737 {
7738 freq = ieee80211_channel_to_frequency(channel,
7739 IEEE80211_BAND_2GHZ);
7740 }
7741 else
7742 {
7743 freq = ieee80211_channel_to_frequency(channel,
7744 IEEE80211_BAND_5GHZ);
7745 }
7746#else
7747 freq = ieee80211_channel_to_frequency(channel);
7748#endif
7749 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
7750 return VOS_STATUS_SUCCESS;
7751 }
7752 }
7753
7754 hddLog(VOS_TRACE_LEVEL_ERROR,
7755 "%s: Invalid Channel [%d]", __func__, channel);
7756 return VOS_STATUS_E_FAILURE;
7757 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007758 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05307759
Jeff Johnson295189b2012-06-20 16:38:30 -07007760 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307761
Jeff Johnson295189b2012-06-20 16:38:30 -07007762}
7763
Viral Modi3a32cc52013-02-08 11:14:52 -08007764/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307765 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08007766 * This function is used to set the channel number
7767 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307768static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08007769 struct ieee80211_channel *chan,
7770 enum nl80211_channel_type channel_type
7771 )
7772{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307773 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08007774 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07007775 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08007776 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307777 hdd_context_t *pHddCtx;
7778 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007779
7780 ENTER();
7781
7782 if( NULL == dev )
7783 {
7784 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007785 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08007786 return -ENODEV;
7787 }
7788 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307789
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307790 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7791 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
7792 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08007793 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307794 "%s: device_mode = %s (%d) freq = %d", __func__,
7795 hdd_device_modetoString(pAdapter->device_mode),
7796 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307797
7798 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7799 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307800 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08007801 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307802 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007803 }
7804
7805 /*
7806 * Do freq to chan conversion
7807 * TODO: for 11a
7808 */
7809
7810 channel = ieee80211_frequency_to_channel(freq);
7811
7812 /* Check freq range */
7813 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
7814 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
7815 {
7816 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007817 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08007818 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
7819 WNI_CFG_CURRENT_CHANNEL_STAMAX);
7820 return -EINVAL;
7821 }
7822
7823 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7824
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05307825 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
7826 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08007827 {
7828 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
7829 {
7830 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007831 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08007832 return -EINVAL;
7833 }
7834 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7835 "%s: set channel to [%d] for device mode =%d",
7836 __func__, channel,pAdapter->device_mode);
7837 }
7838 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08007839 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08007840 )
7841 {
7842 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7843 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
7844 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7845
7846 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
7847 {
7848 /* Link is up then return cant set channel*/
7849 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007850 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08007851 return -EINVAL;
7852 }
7853
7854 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
7855 pHddStaCtx->conn_info.operationChannel = channel;
7856 pRoamProfile->ChannelInfo.ChannelList =
7857 &pHddStaCtx->conn_info.operationChannel;
7858 }
7859 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08007860 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08007861 )
7862 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307863 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
7864 {
7865 if(VOS_STATUS_SUCCESS !=
7866 wlan_hdd_validate_operation_channel(pAdapter,channel))
7867 {
7868 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007869 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307870 return -EINVAL;
7871 }
7872 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7873 }
7874 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08007875 {
7876 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
7877
7878 /* If auto channel selection is configured as enable/ 1 then ignore
7879 channel set by supplicant
7880 */
7881 if ( cfg_param->apAutoChannelSelection )
7882 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307883 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
7884 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08007885 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307886 "%s: set channel to auto channel (0) for device mode =%s (%d)",
7887 __func__, hdd_device_modetoString(pAdapter->device_mode),
7888 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08007889 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307890 else
7891 {
7892 if(VOS_STATUS_SUCCESS !=
7893 wlan_hdd_validate_operation_channel(pAdapter,channel))
7894 {
7895 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007896 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307897 return -EINVAL;
7898 }
7899 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7900 }
Viral Modi3a32cc52013-02-08 11:14:52 -08007901 }
7902 }
7903 else
7904 {
7905 hddLog(VOS_TRACE_LEVEL_FATAL,
7906 "%s: Invalid device mode failed to set valid channel", __func__);
7907 return -EINVAL;
7908 }
7909 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307910 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007911}
7912
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307913static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
7914 struct net_device *dev,
7915 struct ieee80211_channel *chan,
7916 enum nl80211_channel_type channel_type
7917 )
7918{
7919 int ret;
7920
7921 vos_ssr_protect(__func__);
7922 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
7923 vos_ssr_unprotect(__func__);
7924
7925 return ret;
7926}
7927
Jeff Johnson295189b2012-06-20 16:38:30 -07007928#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7929static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7930 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007931#else
7932static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7933 struct cfg80211_beacon_data *params,
7934 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307935 enum nl80211_hidden_ssid hidden_ssid,
7936 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007937#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007938{
7939 tsap_Config_t *pConfig;
7940 beacon_data_t *pBeacon = NULL;
7941 struct ieee80211_mgmt *pMgmt_frame;
7942 v_U8_t *pIe=NULL;
7943 v_U16_t capab_info;
7944 eCsrAuthType RSNAuthType;
7945 eCsrEncryptionType RSNEncryptType;
7946 eCsrEncryptionType mcRSNEncryptType;
7947 int status = VOS_STATUS_SUCCESS;
7948 tpWLAN_SAPEventCB pSapEventCallback;
7949 hdd_hostapd_state_t *pHostapdState;
7950 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
7951 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307952 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007953 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307954 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07007955 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08007956 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05307957 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07007958 v_BOOL_t MFPCapable = VOS_FALSE;
7959 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307960 v_BOOL_t sapEnable11AC =
7961 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07007962 ENTER();
7963
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307964 iniConfig = pHddCtx->cfg_ini;
7965
Jeff Johnson295189b2012-06-20 16:38:30 -07007966 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
7967
7968 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7969
7970 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7971
7972 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
7973
7974 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
7975
7976 //channel is already set in the set_channel Call back
7977 //pConfig->channel = pCommitConfig->channel;
7978
7979 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307980 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07007981 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
7982
7983 pConfig->dtim_period = pBeacon->dtim_period;
7984
Arif Hussain6d2a3322013-11-17 19:50:10 -08007985 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07007986 pConfig->dtim_period);
7987
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08007988 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07007989 {
7990 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007991 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05307992 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
7993 {
7994 tANI_BOOLEAN restartNeeded;
7995 pConfig->ieee80211d = 1;
7996 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
7997 sme_setRegInfo(hHal, pConfig->countryCode);
7998 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
7999 }
8000 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07008001 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07008002 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07008003 pConfig->ieee80211d = 1;
8004 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
8005 sme_setRegInfo(hHal, pConfig->countryCode);
8006 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07008007 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07008008 else
8009 {
8010 pConfig->ieee80211d = 0;
8011 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05308012 /*
8013 * If auto channel is configured i.e. channel is 0,
8014 * so skip channel validation.
8015 */
8016 if( AUTO_CHANNEL_SELECT != pConfig->channel )
8017 {
8018 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
8019 {
8020 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008021 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05308022 return -EINVAL;
8023 }
8024 }
8025 else
8026 {
8027 if(1 != pHddCtx->is_dynamic_channel_range_set)
8028 {
8029 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
8030 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
8031 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
8032 }
8033 pHddCtx->is_dynamic_channel_range_set = 0;
8034 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008035 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07008036 else
Jeff Johnson295189b2012-06-20 16:38:30 -07008037 {
8038 pConfig->ieee80211d = 0;
8039 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308040
8041#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8042 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
8043 pConfig->authType = eSAP_OPEN_SYSTEM;
8044 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
8045 pConfig->authType = eSAP_SHARED_KEY;
8046 else
8047 pConfig->authType = eSAP_AUTO_SWITCH;
8048#else
8049 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
8050 pConfig->authType = eSAP_OPEN_SYSTEM;
8051 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
8052 pConfig->authType = eSAP_SHARED_KEY;
8053 else
8054 pConfig->authType = eSAP_AUTO_SWITCH;
8055#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008056
8057 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308058
8059 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07008060 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
8061
8062 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
8063
8064 /*Set wps station to configured*/
8065 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
8066
8067 if(pIe)
8068 {
8069 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
8070 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008071 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07008072 return -EINVAL;
8073 }
8074 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
8075 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07008076 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07008077 /* Check 15 bit of WPS IE as it contain information for wps state
8078 * WPS state
8079 */
8080 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
8081 {
8082 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
8083 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
8084 {
8085 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
8086 }
8087 }
8088 }
8089 else
8090 {
8091 pConfig->wps_state = SAP_WPS_DISABLED;
8092 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308093 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07008094
c_hpothufe599e92014-06-16 11:38:55 +05308095 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
8096 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
8097 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
8098 eCSR_ENCRYPT_TYPE_NONE;
8099
Jeff Johnson295189b2012-06-20 16:38:30 -07008100 pConfig->RSNWPAReqIELength = 0;
8101 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308102 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07008103 WLAN_EID_RSN);
8104 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308105 {
Jeff Johnson295189b2012-06-20 16:38:30 -07008106 pConfig->RSNWPAReqIELength = pIe[1] + 2;
8107 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
8108 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308109 /* The actual processing may eventually be more extensive than
8110 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07008111 * by the app.
8112 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308113 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07008114 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
8115 &RSNEncryptType,
8116 &mcRSNEncryptType,
8117 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08008118 &MFPCapable,
8119 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07008120 pConfig->pRSNWPAReqIE[1]+2,
8121 pConfig->pRSNWPAReqIE );
8122
8123 if( VOS_STATUS_SUCCESS == status )
8124 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308125 /* Now copy over all the security attributes you have
8126 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07008127 * */
8128 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
8129 pConfig->mcRSNEncryptType = mcRSNEncryptType;
8130 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
8131 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308132 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08008133 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008134 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
8135 }
8136 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308137
Jeff Johnson295189b2012-06-20 16:38:30 -07008138 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
8139 pBeacon->tail, pBeacon->tail_len);
8140
8141 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
8142 {
8143 if (pConfig->pRSNWPAReqIE)
8144 {
8145 /*Mixed mode WPA/WPA2*/
8146 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
8147 pConfig->RSNWPAReqIELength += pIe[1] + 2;
8148 }
8149 else
8150 {
8151 pConfig->RSNWPAReqIELength = pIe[1] + 2;
8152 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
8153 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308154 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07008155 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
8156 &RSNEncryptType,
8157 &mcRSNEncryptType,
8158 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08008159 &MFPCapable,
8160 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07008161 pConfig->pRSNWPAReqIE[1]+2,
8162 pConfig->pRSNWPAReqIE );
8163
8164 if( VOS_STATUS_SUCCESS == status )
8165 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308166 /* Now copy over all the security attributes you have
8167 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07008168 * */
8169 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
8170 pConfig->mcRSNEncryptType = mcRSNEncryptType;
8171 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
8172 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05308173 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08008174 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07008175 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
8176 }
8177 }
8178 }
8179
Jeff Johnson4416a782013-03-25 14:17:50 -07008180 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
8181 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
8182 return -EINVAL;
8183 }
8184
Jeff Johnson295189b2012-06-20 16:38:30 -07008185 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
8186
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008187#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008188 if (params->ssid != NULL)
8189 {
8190 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
8191 pConfig->SSIDinfo.ssid.length = params->ssid_len;
8192 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
8193 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
8194 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008195#else
8196 if (ssid != NULL)
8197 {
8198 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
8199 pConfig->SSIDinfo.ssid.length = ssid_len;
8200 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
8201 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
8202 }
8203#endif
8204
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308205 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07008206 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308207
Jeff Johnson295189b2012-06-20 16:38:30 -07008208 /* default value */
8209 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
8210 pConfig->num_accept_mac = 0;
8211 pConfig->num_deny_mac = 0;
8212
8213 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
8214 pBeacon->tail, pBeacon->tail_len);
8215
8216 /* pIe for black list is following form:
8217 type : 1 byte
8218 length : 1 byte
8219 OUI : 4 bytes
8220 acl type : 1 byte
8221 no of mac addr in black list: 1 byte
8222 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308223 */
8224 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008225 {
8226 pConfig->SapMacaddr_acl = pIe[6];
8227 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08008228 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008229 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308230 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
8231 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008232 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
8233 for (i = 0; i < pConfig->num_deny_mac; i++)
8234 {
8235 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
8236 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308237 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008238 }
8239 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
8240 pBeacon->tail, pBeacon->tail_len);
8241
8242 /* pIe for white list is following form:
8243 type : 1 byte
8244 length : 1 byte
8245 OUI : 4 bytes
8246 acl type : 1 byte
8247 no of mac addr in white list: 1 byte
8248 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308249 */
8250 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008251 {
8252 pConfig->SapMacaddr_acl = pIe[6];
8253 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08008254 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008255 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308256 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
8257 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008258 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
8259 for (i = 0; i < pConfig->num_accept_mac; i++)
8260 {
8261 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
8262 acl_entry++;
8263 }
8264 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308265
Jeff Johnson295189b2012-06-20 16:38:30 -07008266 wlan_hdd_set_sapHwmode(pHostapdAdapter);
8267
Jeff Johnsone7245742012-09-05 17:12:55 -07008268#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08008269 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05308270 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
8271 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05308272 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
8273 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08008274 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
8275 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05308276 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
8277 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07008278 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05308279 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07008280 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05308281 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07008282
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05308283 /* If ACS disable and selected channel <= 14
8284 * OR
8285 * ACS enabled and ACS operating band is choosen as 2.4
8286 * AND
8287 * VHT in 2.4G Disabled
8288 * THEN
8289 * Fallback to 11N mode
8290 */
8291 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
8292 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05308293 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05308294 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07008295 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05308296 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
8297 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07008298 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
8299 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008300 }
8301#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308302
Jeff Johnson295189b2012-06-20 16:38:30 -07008303 // ht_capab is not what the name conveys,this is used for protection bitmap
8304 pConfig->ht_capab =
8305 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
8306
8307 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
8308 {
8309 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
8310 return -EINVAL;
8311 }
8312
8313 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308314 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07008315 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
8316 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308317 pConfig->obssProtEnabled =
8318 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07008319
Chet Lanctot8cecea22014-02-11 19:09:36 -08008320#ifdef WLAN_FEATURE_11W
8321 pConfig->mfpCapable = MFPCapable;
8322 pConfig->mfpRequired = MFPRequired;
8323 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
8324 pConfig->mfpCapable, pConfig->mfpRequired);
8325#endif
8326
Arif Hussain6d2a3322013-11-17 19:50:10 -08008327 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07008328 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08008329 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
8330 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
8331 (int)pConfig->channel);
8332 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
8333 pConfig->SapHw_mode, pConfig->privacy,
8334 pConfig->authType);
8335 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
8336 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
8337 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
8338 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07008339
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308340 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07008341 {
8342 //Bss already started. just return.
8343 //TODO Probably it should update some beacon params.
8344 hddLog( LOGE, "Bss Already started...Ignore the request");
8345 EXIT();
8346 return 0;
8347 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308348
Agarwal Ashish51325b52014-06-16 16:50:49 +05308349 if (vos_max_concurrent_connections_reached()) {
8350 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8351 return -EINVAL;
8352 }
8353
Jeff Johnson295189b2012-06-20 16:38:30 -07008354 pConfig->persona = pHostapdAdapter->device_mode;
8355
Peng Xu2446a892014-09-05 17:21:18 +05308356 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
8357 if ( NULL != psmeConfig)
8358 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05308359 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05308360 sme_GetConfigParam(hHal, psmeConfig);
8361 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05308362#ifdef WLAN_FEATURE_AP_HT40_24G
8363 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
8364 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
8365 && pHddCtx->cfg_ini->apHT40_24GEnabled)
8366 {
8367 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
8368 sme_UpdateConfig (hHal, psmeConfig);
8369 }
8370#endif
Peng Xu2446a892014-09-05 17:21:18 +05308371 vos_mem_free(psmeConfig);
8372 }
Peng Xuafc34e32014-09-25 13:23:55 +05308373 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05308374
Jeff Johnson295189b2012-06-20 16:38:30 -07008375 pSapEventCallback = hdd_hostapd_SAPEventCB;
8376 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
8377 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
8378 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008379 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008380 return -EINVAL;
8381 }
8382
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308383 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07008384 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
8385
8386 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308387
Jeff Johnson295189b2012-06-20 16:38:30 -07008388 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308389 {
8390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008391 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07008392 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07008393 VOS_ASSERT(0);
8394 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308395
Jeff Johnson295189b2012-06-20 16:38:30 -07008396 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05308397 /* Initialize WMM configuation */
8398 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05308399 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008400
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008401#ifdef WLAN_FEATURE_P2P_DEBUG
8402 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
8403 {
8404 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
8405 {
8406 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
8407 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08008408 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008409 }
8410 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
8411 {
8412 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
8413 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08008414 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008415 }
8416 }
8417#endif
8418
Jeff Johnson295189b2012-06-20 16:38:30 -07008419 pHostapdState->bCommit = TRUE;
8420 EXIT();
8421
8422 return 0;
8423}
8424
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008425#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308426static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308427 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008428 struct beacon_parameters *params)
8429{
8430 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308431 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308432 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008433
8434 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308435
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308436 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8437 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
8438 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308439 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
8440 hdd_device_modetoString(pAdapter->device_mode),
8441 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008442
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308443 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8444 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308445 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008446 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308447 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008448 }
8449
Agarwal Ashish51325b52014-06-16 16:50:49 +05308450 if (vos_max_concurrent_connections_reached()) {
8451 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8452 return -EINVAL;
8453 }
8454
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308455 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008456 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008457 )
8458 {
8459 beacon_data_t *old,*new;
8460
8461 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308462
Jeff Johnson295189b2012-06-20 16:38:30 -07008463 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308464 {
8465 hddLog(VOS_TRACE_LEVEL_WARN,
8466 FL("already beacon info added to session(%d)"),
8467 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008468 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308469 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008470
8471 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
8472
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308473 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07008474 {
8475 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008476 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008477 return -EINVAL;
8478 }
8479
8480 pAdapter->sessionCtx.ap.beacon = new;
8481
8482 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
8483 }
8484
8485 EXIT();
8486 return status;
8487}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308488
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308489static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
8490 struct net_device *dev,
8491 struct beacon_parameters *params)
8492{
8493 int ret;
8494
8495 vos_ssr_protect(__func__);
8496 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
8497 vos_ssr_unprotect(__func__);
8498
8499 return ret;
8500}
8501
8502static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008503 struct net_device *dev,
8504 struct beacon_parameters *params)
8505{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308506 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308507 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8508 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308509 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008510
8511 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308512
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308513 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8514 TRACE_CODE_HDD_CFG80211_SET_BEACON,
8515 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
8516 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8517 __func__, hdd_device_modetoString(pAdapter->device_mode),
8518 pAdapter->device_mode);
8519
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308520 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8521 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308522 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008523 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308524 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008525 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308526
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308527 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008528 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308529 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008530 {
8531 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308532
Jeff Johnson295189b2012-06-20 16:38:30 -07008533 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308534
Jeff Johnson295189b2012-06-20 16:38:30 -07008535 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308536 {
8537 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8538 FL("session(%d) old and new heads points to NULL"),
8539 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008540 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308541 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008542
8543 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
8544
8545 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308546 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008547 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008548 return -EINVAL;
8549 }
8550
8551 pAdapter->sessionCtx.ap.beacon = new;
8552
8553 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
8554 }
8555
8556 EXIT();
8557 return status;
8558}
8559
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308560static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
8561 struct net_device *dev,
8562 struct beacon_parameters *params)
8563{
8564 int ret;
8565
8566 vos_ssr_protect(__func__);
8567 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
8568 vos_ssr_unprotect(__func__);
8569
8570 return ret;
8571}
8572
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008573#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8574
8575#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308576static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008577 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008578#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308579static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008580 struct net_device *dev)
8581#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008582{
8583 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07008584 hdd_context_t *pHddCtx = NULL;
8585 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308586 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308587 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008588
8589 ENTER();
8590
8591 if (NULL == pAdapter)
8592 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308593 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008594 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008595 return -ENODEV;
8596 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008597
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308598 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8599 TRACE_CODE_HDD_CFG80211_STOP_AP,
8600 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308601 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8602 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308603 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008604 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308605 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07008606 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008607
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008608 pScanInfo = &pHddCtx->scan_info;
8609
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308610 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8611 __func__, hdd_device_modetoString(pAdapter->device_mode),
8612 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008613
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308614 ret = wlan_hdd_scan_abort(pAdapter);
8615
Girish Gowli4bf7a632014-06-12 13:42:11 +05308616 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07008617 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308618 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8619 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308620
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308621 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07008622 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308623 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8624 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08008625
Jeff Johnsone7245742012-09-05 17:12:55 -07008626 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308627 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07008628 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308629 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008630 }
8631
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05308632 /* Delete all associated STAs before stopping AP/P2P GO */
8633 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05308634 hdd_hostapd_stop(dev);
8635
Jeff Johnson295189b2012-06-20 16:38:30 -07008636 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008637 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008638 )
8639 {
8640 beacon_data_t *old;
8641
8642 old = pAdapter->sessionCtx.ap.beacon;
8643
8644 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308645 {
8646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8647 FL("session(%d) beacon data points to NULL"),
8648 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008649 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308650 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008651
Jeff Johnson295189b2012-06-20 16:38:30 -07008652 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008653
8654 mutex_lock(&pHddCtx->sap_lock);
8655 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8656 {
Jeff Johnson4416a782013-03-25 14:17:50 -07008657 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008658 {
8659 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8660
8661 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
8662
8663 if (!VOS_IS_STATUS_SUCCESS(status))
8664 {
8665 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008666 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008667 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308668 }
8669 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008670 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05308671 /* BSS stopped, clear the active sessions for this device mode */
8672 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008673 }
8674 mutex_unlock(&pHddCtx->sap_lock);
8675
8676 if(status != VOS_STATUS_SUCCESS)
8677 {
8678 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008679 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008680 return -EINVAL;
8681 }
8682
Jeff Johnson4416a782013-03-25 14:17:50 -07008683 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07008684 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
8685 ==eHAL_STATUS_FAILURE)
8686 {
8687 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008688 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008689 }
8690
Jeff Johnson4416a782013-03-25 14:17:50 -07008691 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07008692 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8693 eANI_BOOLEAN_FALSE) )
8694 {
8695 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008696 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008697 }
8698
8699 // Reset WNI_CFG_PROBE_RSP Flags
8700 wlan_hdd_reset_prob_rspies(pAdapter);
8701
8702 pAdapter->sessionCtx.ap.beacon = NULL;
8703 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008704#ifdef WLAN_FEATURE_P2P_DEBUG
8705 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
8706 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
8707 {
8708 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
8709 "GO got removed");
8710 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
8711 }
8712#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008713 }
8714 EXIT();
8715 return status;
8716}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008717
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308718#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8719static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
8720 struct net_device *dev)
8721{
8722 int ret;
8723
8724 vos_ssr_protect(__func__);
8725 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
8726 vos_ssr_unprotect(__func__);
8727
8728 return ret;
8729}
8730#else
8731static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
8732 struct net_device *dev)
8733{
8734 int ret;
8735
8736 vos_ssr_protect(__func__);
8737 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
8738 vos_ssr_unprotect(__func__);
8739
8740 return ret;
8741}
8742#endif
8743
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008744#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
8745
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308746static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308747 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008748 struct cfg80211_ap_settings *params)
8749{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308750 hdd_adapter_t *pAdapter;
8751 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308752 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008753
8754 ENTER();
8755
Girish Gowlib143d7a2015-02-18 19:39:55 +05308756 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008757 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05308759 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308760 return -ENODEV;
8761 }
8762
8763 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8764 if (NULL == pAdapter)
8765 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308766 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308767 "%s: HDD adapter is Null", __func__);
8768 return -ENODEV;
8769 }
8770
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308771 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8772 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
8773 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308774 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
8775 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308776 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308777 "%s: HDD adapter magic is invalid", __func__);
8778 return -ENODEV;
8779 }
8780
8781 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308782 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308783 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308784 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308785 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308786 }
8787
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308788 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
8789 __func__, hdd_device_modetoString(pAdapter->device_mode),
8790 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308791
8792 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008793 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008794 )
8795 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308796 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008797
8798 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308799
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008800 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308801 {
8802 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
8803 FL("already beacon info added to session(%d)"),
8804 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008805 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308806 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008807
Girish Gowlib143d7a2015-02-18 19:39:55 +05308808#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8809 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
8810 &new,
8811 &params->beacon);
8812#else
8813 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
8814 &new,
8815 &params->beacon,
8816 params->dtim_period);
8817#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008818
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308819 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008820 {
8821 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308822 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008823 return -EINVAL;
8824 }
8825 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08008826#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07008827 wlan_hdd_cfg80211_set_channel(wiphy, dev,
8828#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
8829 params->channel, params->channel_type);
8830#else
8831 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
8832#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08008833#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008834 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308835 params->ssid_len, params->hidden_ssid,
8836 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008837 }
8838
8839 EXIT();
8840 return status;
8841}
8842
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308843static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
8844 struct net_device *dev,
8845 struct cfg80211_ap_settings *params)
8846{
8847 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008848
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308849 vos_ssr_protect(__func__);
8850 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
8851 vos_ssr_unprotect(__func__);
8852
8853 return ret;
8854}
8855
8856static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008857 struct net_device *dev,
8858 struct cfg80211_beacon_data *params)
8859{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308860 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308861 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308862 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008863
8864 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308865
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308866 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8867 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
8868 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08008869 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008870 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308871
8872 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8873 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308874 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008875 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308876 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008877 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008878
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308879 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008880 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308881 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008882 {
8883 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308884
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008885 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308886
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008887 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308888 {
8889 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8890 FL("session(%d) beacon data points to NULL"),
8891 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008892 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308893 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008894
8895 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
8896
8897 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308898 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008899 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008900 return -EINVAL;
8901 }
8902
8903 pAdapter->sessionCtx.ap.beacon = new;
8904
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308905 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
8906 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008907 }
8908
8909 EXIT();
8910 return status;
8911}
8912
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308913static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8914 struct net_device *dev,
8915 struct cfg80211_beacon_data *params)
8916{
8917 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008918
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308919 vos_ssr_protect(__func__);
8920 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
8921 vos_ssr_unprotect(__func__);
8922
8923 return ret;
8924}
8925
8926#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008927
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308928static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008929 struct net_device *dev,
8930 struct bss_parameters *params)
8931{
8932 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308933 hdd_context_t *pHddCtx;
8934 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008935
8936 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308937
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308938 if (NULL == pAdapter)
8939 {
8940 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8941 "%s: HDD adapter is Null", __func__);
8942 return -ENODEV;
8943 }
8944 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308945 ret = wlan_hdd_validate_context(pHddCtx);
8946 if (0 != ret)
8947 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308948 return ret;
8949 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308950 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8951 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
8952 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308953 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8954 __func__, hdd_device_modetoString(pAdapter->device_mode),
8955 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008956
8957 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008958 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308959 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008960 {
8961 /* ap_isolate == -1 means that in change bss, upper layer doesn't
8962 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308963 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07008964 {
8965 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308966 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008967 }
8968
8969 EXIT();
8970 return 0;
8971}
8972
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308973static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
8974 struct net_device *dev,
8975 struct bss_parameters *params)
8976{
8977 int ret;
8978
8979 vos_ssr_protect(__func__);
8980 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
8981 vos_ssr_unprotect(__func__);
8982
8983 return ret;
8984}
Kiet Lam10841362013-11-01 11:36:50 +05308985/* FUNCTION: wlan_hdd_change_country_code_cd
8986* to wait for contry code completion
8987*/
8988void* wlan_hdd_change_country_code_cb(void *pAdapter)
8989{
8990 hdd_adapter_t *call_back_pAdapter = pAdapter;
8991 complete(&call_back_pAdapter->change_country_code);
8992 return NULL;
8993}
8994
Jeff Johnson295189b2012-06-20 16:38:30 -07008995/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308996 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07008997 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
8998 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308999int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009000 struct net_device *ndev,
9001 enum nl80211_iftype type,
9002 u32 *flags,
9003 struct vif_params *params
9004 )
9005{
9006 struct wireless_dev *wdev;
9007 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08009008 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07009009 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009010 tCsrRoamProfile *pRoamProfile = NULL;
9011 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309012 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009013 eMib_dot11DesiredBssType connectedBssType;
9014 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309015 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07009016
9017 ENTER();
9018
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309019 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08009020 {
9021 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9022 "%s: Adapter context is null", __func__);
9023 return VOS_STATUS_E_FAILURE;
9024 }
9025
9026 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9027 if (!pHddCtx)
9028 {
9029 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9030 "%s: HDD context is null", __func__);
9031 return VOS_STATUS_E_FAILURE;
9032 }
9033
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309034 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9035 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
9036 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309037 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309038 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07009039 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309040 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009041 }
9042
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309043 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9044 __func__, hdd_device_modetoString(pAdapter->device_mode),
9045 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009046
Agarwal Ashish51325b52014-06-16 16:50:49 +05309047 if (vos_max_concurrent_connections_reached()) {
9048 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
9049 return -EINVAL;
9050 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309051 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07009052 wdev = ndev->ieee80211_ptr;
9053
9054#ifdef WLAN_BTAMP_FEATURE
9055 if((NL80211_IFTYPE_P2P_CLIENT == type)||
9056 (NL80211_IFTYPE_ADHOC == type)||
9057 (NL80211_IFTYPE_AP == type)||
9058 (NL80211_IFTYPE_P2P_GO == type))
9059 {
9060 pHddCtx->isAmpAllowed = VOS_FALSE;
9061 // stop AMP traffic
9062 status = WLANBAP_StopAmp();
9063 if(VOS_STATUS_SUCCESS != status )
9064 {
9065 pHddCtx->isAmpAllowed = VOS_TRUE;
9066 hddLog(VOS_TRACE_LEVEL_FATAL,
9067 "%s: Failed to stop AMP", __func__);
9068 return -EINVAL;
9069 }
9070 }
9071#endif //WLAN_BTAMP_FEATURE
9072 /* Reset the current device mode bit mask*/
9073 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
9074
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +05309075 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
9076 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
9077 (type == NL80211_IFTYPE_P2P_GO)))
9078 {
9079 /* Notify Mode change in case of concurrency.
9080 * Below function invokes TDLS teardown Functionality Since TDLS is
9081 * not Supported in case of concurrency i.e Once P2P session
9082 * is detected disable offchannel and teardown TDLS links
9083 */
9084 hddLog(LOG1,
9085 FL("Device mode = %d Interface type = %d"),
9086 pAdapter->device_mode, type);
9087 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
9088 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +05309089
Jeff Johnson295189b2012-06-20 16:38:30 -07009090 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07009091 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07009092 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07009093 )
9094 {
9095 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08009096 if (!pWextState)
9097 {
9098 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9099 "%s: pWextState is null", __func__);
9100 return VOS_STATUS_E_FAILURE;
9101 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009102 pRoamProfile = &pWextState->roamProfile;
9103 LastBSSType = pRoamProfile->BSSType;
9104
9105 switch (type)
9106 {
9107 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07009108 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07009109 hddLog(VOS_TRACE_LEVEL_INFO,
9110 "%s: setting interface Type to INFRASTRUCTURE", __func__);
9111 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07009112#ifdef WLAN_FEATURE_11AC
9113 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
9114 {
9115 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
9116 }
9117#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309118 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07009119 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009120 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08009121 //Check for sub-string p2p to confirm its a p2p interface
9122 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309123 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +05309124#ifdef FEATURE_WLAN_TDLS
9125 mutex_lock(&pHddCtx->tdls_lock);
9126 wlan_hdd_tdls_exit(pAdapter, TRUE);
9127 mutex_unlock(&pHddCtx->tdls_lock);
9128#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -08009129 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
9130 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
9131 }
9132 else
9133 {
9134 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07009135 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08009136 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009137 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05309138
Jeff Johnson295189b2012-06-20 16:38:30 -07009139 case NL80211_IFTYPE_ADHOC:
9140 hddLog(VOS_TRACE_LEVEL_INFO,
9141 "%s: setting interface Type to ADHOC", __func__);
9142 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
9143 pRoamProfile->phyMode =
9144 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07009145 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07009146 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +05309147 hdd_set_ibss_ops( pAdapter );
9148 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +05309149
9150 status = hdd_sta_id_hash_attach(pAdapter);
9151 if (VOS_STATUS_SUCCESS != status) {
9152 hddLog(VOS_TRACE_LEVEL_ERROR,
9153 FL("Failed to initialize hash for IBSS"));
9154 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009155 break;
9156
9157 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07009158 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009159 {
9160 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
9161 "%s: setting interface Type to %s", __func__,
9162 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
9163
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08009164 //Cancel any remain on channel for GO mode
9165 if (NL80211_IFTYPE_P2P_GO == type)
9166 {
9167 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
9168 }
Mohit Khanna0f232092012-09-11 14:46:08 -07009169 if (NL80211_IFTYPE_AP == type)
9170 {
9171 /* As Loading WLAN Driver one interface being created for p2p device
9172 * address. This will take one HW STA and the max number of clients
9173 * that can connect to softAP will be reduced by one. so while changing
9174 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
9175 * interface as it is not required in SoftAP mode.
9176 */
9177
9178 // Get P2P Adapter
9179 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
9180
9181 if (pP2pAdapter)
9182 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05309183 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05309184 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07009185 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
9186 }
9187 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05309188 //Disable IMPS & BMPS for SAP/GO
9189 if(VOS_STATUS_E_FAILURE ==
9190 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
9191 {
9192 //Fail to Exit BMPS
9193 VOS_ASSERT(0);
9194 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05309195
9196 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
9197
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309198#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07009199
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309200 /* A Mutex Lock is introduced while changing the mode to
9201 * protect the concurrent access for the Adapters by TDLS
9202 * module.
9203 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309204 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309205#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009206 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05309207 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009208 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07009209 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
9210 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309211#ifdef FEATURE_WLAN_TDLS
9212 mutex_unlock(&pHddCtx->tdls_lock);
9213#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07009214 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
9215 (pConfig->apRandomBssidEnabled))
9216 {
9217 /* To meet Android requirements create a randomized
9218 MAC address of the form 02:1A:11:Fx:xx:xx */
9219 get_random_bytes(&ndev->dev_addr[3], 3);
9220 ndev->dev_addr[0] = 0x02;
9221 ndev->dev_addr[1] = 0x1A;
9222 ndev->dev_addr[2] = 0x11;
9223 ndev->dev_addr[3] |= 0xF0;
9224 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
9225 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08009226 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
9227 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07009228 }
9229
Jeff Johnson295189b2012-06-20 16:38:30 -07009230 hdd_set_ap_ops( pAdapter->dev );
9231
Kiet Lam10841362013-11-01 11:36:50 +05309232 /* This is for only SAP mode where users can
9233 * control country through ini.
9234 * P2P GO follows station country code
9235 * acquired during the STA scanning. */
9236 if((NL80211_IFTYPE_AP == type) &&
9237 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
9238 {
9239 int status = 0;
9240 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
9241 "%s: setting country code from INI ", __func__);
9242 init_completion(&pAdapter->change_country_code);
9243 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
9244 (void *)(tSmeChangeCountryCallback)
9245 wlan_hdd_change_country_code_cb,
9246 pConfig->apCntryCode, pAdapter,
9247 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309248 eSIR_FALSE,
9249 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05309250 if (eHAL_STATUS_SUCCESS == status)
9251 {
9252 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309253 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05309254 &pAdapter->change_country_code,
9255 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309256 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05309257 {
9258 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309259 FL("SME Timed out while setting country code %ld"),
9260 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08009261
9262 if (pHddCtx->isLogpInProgress)
9263 {
9264 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9265 "%s: LOGP in Progress. Ignore!!!", __func__);
9266 return -EAGAIN;
9267 }
Kiet Lam10841362013-11-01 11:36:50 +05309268 }
9269 }
9270 else
9271 {
9272 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009273 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05309274 return -EINVAL;
9275 }
9276 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009277 status = hdd_init_ap_mode(pAdapter);
9278 if(status != VOS_STATUS_SUCCESS)
9279 {
9280 hddLog(VOS_TRACE_LEVEL_FATAL,
9281 "%s: Error initializing the ap mode", __func__);
9282 return -EINVAL;
9283 }
9284 hdd_set_conparam(1);
9285
Nirav Shah7e3c8132015-06-22 23:51:42 +05309286 status = hdd_sta_id_hash_attach(pAdapter);
9287 if (VOS_STATUS_SUCCESS != status)
9288 {
9289 hddLog(VOS_TRACE_LEVEL_ERROR,
9290 FL("Failed to initialize hash for AP"));
9291 return -EINVAL;
9292 }
9293
Jeff Johnson295189b2012-06-20 16:38:30 -07009294 /*interface type changed update in wiphy structure*/
9295 if(wdev)
9296 {
9297 wdev->iftype = type;
9298 pHddCtx->change_iface = type;
9299 }
9300 else
9301 {
9302 hddLog(VOS_TRACE_LEVEL_ERROR,
9303 "%s: ERROR !!!! Wireless dev is NULL", __func__);
9304 return -EINVAL;
9305 }
9306 goto done;
9307 }
9308
9309 default:
9310 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
9311 __func__);
9312 return -EOPNOTSUPP;
9313 }
9314 }
9315 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009316 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009317 )
9318 {
9319 switch(type)
9320 {
9321 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07009322 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07009323 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05309324
9325 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309326#ifdef FEATURE_WLAN_TDLS
9327
9328 /* A Mutex Lock is introduced while changing the mode to
9329 * protect the concurrent access for the Adapters by TDLS
9330 * module.
9331 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309332 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309333#endif
c_hpothu002231a2015-02-05 14:58:51 +05309334 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009335 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08009336 //Check for sub-string p2p to confirm its a p2p interface
9337 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08009338 {
9339 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
9340 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
9341 }
9342 else
9343 {
9344 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07009345 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08009346 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009347 hdd_set_conparam(0);
9348 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07009349 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
9350 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309351#ifdef FEATURE_WLAN_TDLS
9352 mutex_unlock(&pHddCtx->tdls_lock);
9353#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05309354 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07009355 if( VOS_STATUS_SUCCESS != status )
9356 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07009357 /* In case of JB, for P2P-GO, only change interface will be called,
9358 * This is the right place to enable back bmps_imps()
9359 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309360 if (pHddCtx->hdd_wlan_suspended)
9361 {
9362 hdd_set_pwrparams(pHddCtx);
9363 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009364 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009365 goto done;
9366 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07009367 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009368 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07009369 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
9370 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009371 goto done;
9372 default:
9373 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
9374 __func__);
9375 return -EOPNOTSUPP;
9376
9377 }
9378
9379 }
9380 else
9381 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309382 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
9383 __func__, hdd_device_modetoString(pAdapter->device_mode),
9384 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009385 return -EOPNOTSUPP;
9386 }
9387
9388
9389 if(pRoamProfile)
9390 {
9391 if ( LastBSSType != pRoamProfile->BSSType )
9392 {
9393 /*interface type changed update in wiphy structure*/
9394 wdev->iftype = type;
9395
9396 /*the BSS mode changed, We need to issue disconnect
9397 if connected or in IBSS disconnect state*/
9398 if ( hdd_connGetConnectedBssType(
9399 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
9400 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
9401 {
9402 /*need to issue a disconnect to CSR.*/
9403 INIT_COMPLETION(pAdapter->disconnect_comp_var);
9404 if( eHAL_STATUS_SUCCESS ==
9405 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
9406 pAdapter->sessionId,
9407 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
9408 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309409 ret = wait_for_completion_interruptible_timeout(
9410 &pAdapter->disconnect_comp_var,
9411 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
9412 if (ret <= 0)
9413 {
9414 hddLog(VOS_TRACE_LEVEL_ERROR,
9415 FL("wait on disconnect_comp_var failed %ld"), ret);
9416 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009417 }
9418 }
9419 }
9420 }
9421
9422done:
9423 /*set bitmask based on updated value*/
9424 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07009425
9426 /* Only STA mode support TM now
9427 * all other mode, TM feature should be disabled */
9428 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
9429 (~VOS_STA & pHddCtx->concurrency_mode) )
9430 {
9431 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
9432 }
9433
Jeff Johnson295189b2012-06-20 16:38:30 -07009434#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309435 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05309436 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07009437 {
9438 //we are ok to do AMP
9439 pHddCtx->isAmpAllowed = VOS_TRUE;
9440 }
9441#endif //WLAN_BTAMP_FEATURE
9442 EXIT();
9443 return 0;
9444}
9445
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05309446/*
9447 * FUNCTION: wlan_hdd_cfg80211_change_iface
9448 * wrapper function to protect the actual implementation from SSR.
9449 */
9450int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
9451 struct net_device *ndev,
9452 enum nl80211_iftype type,
9453 u32 *flags,
9454 struct vif_params *params
9455 )
9456{
9457 int ret;
9458
9459 vos_ssr_protect(__func__);
9460 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
9461 vos_ssr_unprotect(__func__);
9462
9463 return ret;
9464}
9465
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009466#ifdef FEATURE_WLAN_TDLS
9467static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309468 struct net_device *dev,
9469#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
9470 const u8 *mac,
9471#else
9472 u8 *mac,
9473#endif
9474 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009475{
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009476 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009477 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309478 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309479 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05309480 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309481 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009482
9483 ENTER();
9484
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05309485 if (!dev) {
9486 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
9487 return -EINVAL;
9488 }
9489
9490 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9491 if (!pAdapter) {
9492 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
9493 return -EINVAL;
9494 }
9495
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309496 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009497 {
9498 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9499 "Invalid arguments");
9500 return -EINVAL;
9501 }
Hoonki Lee27511902013-03-14 18:19:06 -07009502
9503 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
9504 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
9505 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309506 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -07009507 "%s: TDLS mode is disabled OR not enabled in FW."
9508 MAC_ADDRESS_STR " Request declined.",
9509 __func__, MAC_ADDR_ARRAY(mac));
9510 return -ENOTSUPP;
9511 }
9512
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009513 if (pHddCtx->isLogpInProgress)
9514 {
9515 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9516 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05309517 wlan_hdd_tdls_set_link_status(pAdapter,
9518 mac,
9519 eTDLS_LINK_IDLE,
9520 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009521 return -EBUSY;
9522 }
9523
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309524 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05309525 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009526
9527 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309528 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009529 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
9530 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309531 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009532 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009533 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309534 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009535
9536 /* in add station, we accept existing valid staId if there is */
9537 if ((0 == update) &&
9538 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
9539 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009540 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309541 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009542 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009543 " link_status %d. staId %d. add station ignored.",
9544 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
9545 return 0;
9546 }
9547 /* in change station, we accept only when staId is valid */
9548 if ((1 == update) &&
9549 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
9550 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
9551 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009553 "%s: " MAC_ADDRESS_STR
9554 " link status %d. staId %d. change station %s.",
9555 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
9556 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
9557 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009558 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009559
9560 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +05309561 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009562 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009563 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9564 "%s: " MAC_ADDRESS_STR
9565 " TDLS setup is ongoing. Request declined.",
9566 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07009567 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009568 }
9569
9570 /* first to check if we reached to maximum supported TDLS peer.
9571 TODO: for now, return -EPERM looks working fine,
9572 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309573 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
9574 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009575 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009576 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9577 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309578 " TDLS Max peer already connected. Request declined."
9579 " Num of peers (%d), Max allowed (%d).",
9580 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
9581 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009582 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009583 }
9584 else
9585 {
9586 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309587 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009588 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009589 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009590 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9591 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
9592 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009593 return -EPERM;
9594 }
9595 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009596 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05309597 wlan_hdd_tdls_set_link_status(pAdapter,
9598 mac,
9599 eTDLS_LINK_CONNECTING,
9600 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009601
Jeff Johnsond75fe012013-04-06 10:53:06 -07009602 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309603 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009604 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309605 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009606 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07009607 if(StaParams->htcap_present)
9608 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009610 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309611 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009612 "ht_capa->extended_capabilities: %0x",
9613 StaParams->HTCap.extendedHtCapInfo);
9614 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309615 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009616 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009618 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07009619 if(StaParams->vhtcap_present)
9620 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309621 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009622 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
9623 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
9624 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
9625 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009626 {
9627 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009628 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009629 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009631 "[%d]: %x ", i, StaParams->supported_rates[i]);
9632 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07009633 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309634 else if ((1 == update) && (NULL == StaParams))
9635 {
9636 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9637 "%s : update is true, but staParams is NULL. Error!", __func__);
9638 return -EPERM;
9639 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009640
9641 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
9642
9643 if (!update)
9644 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309645 /*Before adding sta make sure that device exited from BMPS*/
9646 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
9647 {
9648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9649 "%s: Adding tdls peer sta. Disable BMPS", __func__);
9650 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
9651 if (status != VOS_STATUS_SUCCESS) {
9652 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
9653 }
9654 }
9655
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309656 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009657 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309658 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309659 hddLog(VOS_TRACE_LEVEL_ERROR,
9660 FL("Failed to add TDLS peer STA. Enable Bmps"));
9661 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309662 return -EPERM;
9663 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009664 }
9665 else
9666 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309667 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009668 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309669 if (ret != eHAL_STATUS_SUCCESS) {
9670 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
9671 return -EPERM;
9672 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009673 }
9674
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309675 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009676 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
9677
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309678 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009679 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309681 "%s: timeout waiting for tdls add station indication %ld",
9682 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009683 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009684 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309685
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009686 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
9687 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009688 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009689 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009690 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009691 }
9692
9693 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07009694
9695error:
Atul Mittal115287b2014-07-08 13:26:33 +05309696 wlan_hdd_tdls_set_link_status(pAdapter,
9697 mac,
9698 eTDLS_LINK_IDLE,
9699 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009700 return -EPERM;
9701
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009702}
9703#endif
9704
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309705static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009706 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309707#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
9708 const u8 *mac,
9709#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009710 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309711#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009712 struct station_parameters *params)
9713{
9714 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309715 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309716 hdd_context_t *pHddCtx;
9717 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009718 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309719 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009720#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009721 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009722 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309723 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009724#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009725
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309726 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309727
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309728 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +05309729 if ((NULL == pAdapter))
9730 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309731 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309732 "invalid adapter ");
9733 return -EINVAL;
9734 }
9735
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309736 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9737 TRACE_CODE_HDD_CHANGE_STATION,
9738 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05309739 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05309740
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309741 ret = wlan_hdd_validate_context(pHddCtx);
9742 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05309743 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309744 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309745 }
9746
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309747 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9748
9749 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009750 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309751 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9752 "invalid HDD station context");
9753 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009754 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009755 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
9756
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009757 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
9758 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07009759 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009760 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07009761 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309762 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07009763 WLANTL_STA_AUTHENTICATED);
9764
Gopichand Nakkala29149562013-05-10 21:43:41 +05309765 if (status != VOS_STATUS_SUCCESS)
9766 {
9767 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9768 "%s: Not able to change TL state to AUTHENTICATED", __func__);
9769 return -EINVAL;
9770 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009771 }
9772 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07009773 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
9774 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309775#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009776 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
9777 StaParams.capability = params->capability;
9778 StaParams.uapsd_queues = params->uapsd_queues;
9779 StaParams.max_sp = params->max_sp;
9780
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309781 /* Convert (first channel , number of channels) tuple to
9782 * the total list of channels. This goes with the assumption
9783 * that if the first channel is < 14, then the next channels
9784 * are an incremental of 1 else an incremental of 4 till the number
9785 * of channels.
9786 */
9787 if (0 != params->supported_channels_len) {
9788 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
9789 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
9790 {
9791 int wifi_chan_index;
9792 StaParams.supported_channels[j] = params->supported_channels[i];
9793 wifi_chan_index =
9794 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
9795 no_of_channels = params->supported_channels[i+1];
9796 for(k=1; k <= no_of_channels; k++)
9797 {
9798 StaParams.supported_channels[j+1] =
9799 StaParams.supported_channels[j] + wifi_chan_index;
9800 j+=1;
9801 }
9802 }
9803 StaParams.supported_channels_len = j;
9804 }
9805 vos_mem_copy(StaParams.supported_oper_classes,
9806 params->supported_oper_classes,
9807 params->supported_oper_classes_len);
9808 StaParams.supported_oper_classes_len =
9809 params->supported_oper_classes_len;
9810
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009811 if (0 != params->ext_capab_len)
9812 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
9813 sizeof(StaParams.extn_capability));
9814
9815 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07009816 {
9817 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009818 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07009819 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009820
9821 StaParams.supported_rates_len = params->supported_rates_len;
9822
9823 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
9824 * The supported_rates array , for all the structures propogating till Add Sta
9825 * to the firmware has to be modified , if the supplicant (ieee80211) is
9826 * modified to send more rates.
9827 */
9828
9829 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
9830 */
9831 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
9832 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
9833
9834 if (0 != StaParams.supported_rates_len) {
9835 int i = 0;
9836 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
9837 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009838 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009839 "Supported Rates with Length %d", StaParams.supported_rates_len);
9840 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009841 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009842 "[%d]: %0x", i, StaParams.supported_rates[i]);
9843 }
9844
9845 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07009846 {
9847 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009848 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07009849 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009850
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009851 if (0 != params->ext_capab_len ) {
9852 /*Define A Macro : TODO Sunil*/
9853 if ((1<<4) & StaParams.extn_capability[3]) {
9854 isBufSta = 1;
9855 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309856 /* TDLS Channel Switching Support */
9857 if ((1<<6) & StaParams.extn_capability[3]) {
9858 isOffChannelSupported = 1;
9859 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009860 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309861 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
9862 &StaParams, isBufSta,
9863 isOffChannelSupported);
9864
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309865 if (VOS_STATUS_SUCCESS != status) {
9866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9867 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
9868 return -EINVAL;
9869 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009870 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
9871
9872 if (VOS_STATUS_SUCCESS != status) {
9873 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9874 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
9875 return -EINVAL;
9876 }
9877 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009878#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05309879 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009880 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009881 return status;
9882}
9883
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309884#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
9885static int wlan_hdd_change_station(struct wiphy *wiphy,
9886 struct net_device *dev,
9887 const u8 *mac,
9888 struct station_parameters *params)
9889#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309890static int wlan_hdd_change_station(struct wiphy *wiphy,
9891 struct net_device *dev,
9892 u8 *mac,
9893 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309894#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309895{
9896 int ret;
9897
9898 vos_ssr_protect(__func__);
9899 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
9900 vos_ssr_unprotect(__func__);
9901
9902 return ret;
9903}
9904
Jeff Johnson295189b2012-06-20 16:38:30 -07009905/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309906 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009907 * This function is used to initialize the key information
9908 */
9909#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309910static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009911 struct net_device *ndev,
9912 u8 key_index, bool pairwise,
9913 const u8 *mac_addr,
9914 struct key_params *params
9915 )
9916#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309917static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009918 struct net_device *ndev,
9919 u8 key_index, const u8 *mac_addr,
9920 struct key_params *params
9921 )
9922#endif
9923{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009924 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07009925 tCsrRoamSetKey setKey;
9926 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309927 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009928 v_U32_t roamId= 0xFF;
9929 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009930 hdd_hostapd_state_t *pHostapdState;
9931 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009932 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309933 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009934
9935 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309936
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309937 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9938 TRACE_CODE_HDD_CFG80211_ADD_KEY,
9939 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309940 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9941 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309942 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009943 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309944 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009945 }
9946
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309947 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9948 __func__, hdd_device_modetoString(pAdapter->device_mode),
9949 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009950
9951 if (CSR_MAX_NUM_KEY <= key_index)
9952 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009953 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009954 key_index);
9955
9956 return -EINVAL;
9957 }
9958
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009959 if (CSR_MAX_KEY_LEN < params->key_len)
9960 {
9961 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
9962 params->key_len);
9963
9964 return -EINVAL;
9965 }
9966
9967 hddLog(VOS_TRACE_LEVEL_INFO,
9968 "%s: called with key index = %d & key length %d",
9969 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009970
9971 /*extract key idx, key len and key*/
9972 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9973 setKey.keyId = key_index;
9974 setKey.keyLength = params->key_len;
9975 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
9976
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009977 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009978 {
9979 case WLAN_CIPHER_SUITE_WEP40:
9980 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
9981 break;
9982
9983 case WLAN_CIPHER_SUITE_WEP104:
9984 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
9985 break;
9986
9987 case WLAN_CIPHER_SUITE_TKIP:
9988 {
9989 u8 *pKey = &setKey.Key[0];
9990 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
9991
9992 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
9993
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009994 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07009995
9996 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009997 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009998 |--------------|----------|----------|
9999 <---16bytes---><--8bytes--><--8bytes-->
10000
10001 */
10002 /*Sme expects the 32 bytes key to be in the below order
10003
10004 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010005 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -070010006 |--------------|----------|----------|
10007 <---16bytes---><--8bytes--><--8bytes-->
10008 */
10009 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010010 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -070010011
10012 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010013 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070010014
10015 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010016 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -070010017
10018
10019 break;
10020 }
10021
10022 case WLAN_CIPHER_SUITE_CCMP:
10023 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
10024 break;
10025
10026#ifdef FEATURE_WLAN_WAPI
10027 case WLAN_CIPHER_SUITE_SMS4:
10028 {
10029 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
10030 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
10031 params->key, params->key_len);
10032 return 0;
10033 }
10034#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070010035
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080010036#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070010037 case WLAN_CIPHER_SUITE_KRK:
10038 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
10039 break;
10040#endif
Chet Lanctot186b5732013-03-18 10:26:30 -070010041
10042#ifdef WLAN_FEATURE_11W
10043 case WLAN_CIPHER_SUITE_AES_CMAC:
10044 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -070010045 break;
Chet Lanctot186b5732013-03-18 10:26:30 -070010046#endif
10047
Jeff Johnson295189b2012-06-20 16:38:30 -070010048 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -070010049 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070010050 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010051 status = -EOPNOTSUPP;
10052 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070010053 }
10054
10055 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
10056 __func__, setKey.encType);
10057
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010058 if (
Jeff Johnson295189b2012-06-20 16:38:30 -070010059#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10060 (!pairwise)
10061#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010062 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -070010063#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010064 )
10065 {
10066 /* set group key*/
10067 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10068 "%s- %d: setting Broadcast key",
10069 __func__, __LINE__);
10070 setKey.keyDirection = eSIR_RX_ONLY;
10071 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
10072 }
10073 else
10074 {
10075 /* set pairwise key*/
10076 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10077 "%s- %d: setting pairwise key",
10078 __func__, __LINE__);
10079 setKey.keyDirection = eSIR_TX_RX;
10080 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
10081 }
10082 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
10083 {
10084 setKey.keyDirection = eSIR_TX_RX;
10085 /*Set the group key*/
10086 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
10087 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -070010088
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010089 if ( 0 != status )
10090 {
10091 hddLog(VOS_TRACE_LEVEL_ERROR,
10092 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010093 status = -EINVAL;
10094 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010095 }
10096 /*Save the keys here and call sme_RoamSetKey for setting
10097 the PTK after peer joins the IBSS network*/
10098 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
10099 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010100 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070010101 }
Gopichand Nakkala29149562013-05-10 21:43:41 +053010102 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
10103 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
10104 {
Jeff Johnson295189b2012-06-20 16:38:30 -070010105 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010106 if( pHostapdState->bssState == BSS_START )
10107 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -070010108 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10109 vos_status = wlan_hdd_check_ula_done(pAdapter);
10110
10111 if ( vos_status != VOS_STATUS_SUCCESS )
10112 {
10113 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10114 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
10115 __LINE__, vos_status );
10116
10117 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
10118
10119 status = -EINVAL;
10120 goto end;
10121 }
10122
Jeff Johnson295189b2012-06-20 16:38:30 -070010123 status = WLANSAP_SetKeySta( pVosContext, &setKey);
10124
10125 if ( status != eHAL_STATUS_SUCCESS )
10126 {
10127 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10128 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
10129 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010130 status = -EINVAL;
10131 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070010132 }
10133 }
10134
10135 /* Saving WEP keys */
10136 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
10137 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
10138 {
10139 //Save the wep key in ap context. Issue setkey after the BSS is started.
10140 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
10141 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
10142 }
10143 else
10144 {
10145 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010146 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010147 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
10148 }
10149 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010150 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
10151 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -070010152 {
10153 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10154 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10155
Gopichand Nakkala3d295922013-05-07 16:19:14 +053010156#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10157 if (!pairwise)
10158#else
10159 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
10160#endif
10161 {
10162 /* set group key*/
10163 if (pHddStaCtx->roam_info.deferKeyComplete)
10164 {
10165 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10166 "%s- %d: Perform Set key Complete",
10167 __func__, __LINE__);
10168 hdd_PerformRoamSetKeyComplete(pAdapter);
10169 }
10170 }
10171
Jeff Johnson295189b2012-06-20 16:38:30 -070010172 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
10173
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -080010174 pWextState->roamProfile.Keys.defaultIndex = key_index;
10175
10176
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070010177 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010178 params->key, params->key_len);
10179
Gopichand Nakkala3d295922013-05-07 16:19:14 +053010180
Jeff Johnson295189b2012-06-20 16:38:30 -070010181 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
10182
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010183 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070010184 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010185 __func__, setKey.peerMac[0], setKey.peerMac[1],
10186 setKey.peerMac[2], setKey.peerMac[3],
10187 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070010188 setKey.keyDirection);
10189
Nirav Shah4b53d4b2015-05-08 05:35:00 -070010190 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +053010191
Nirav Shah4b53d4b2015-05-08 05:35:00 -070010192 if ( vos_status != VOS_STATUS_SUCCESS )
10193 {
10194 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010195 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
10196 __LINE__, vos_status );
10197
Nirav Shah4b53d4b2015-05-08 05:35:00 -070010198 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010199
Nirav Shah4b53d4b2015-05-08 05:35:00 -070010200 status = -EINVAL;
10201 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070010202
10203 }
10204
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010205#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +053010206 /* The supplicant may attempt to set the PTK once pre-authentication
10207 is done. Save the key in the UMAC and include it in the ADD BSS
10208 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010209 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +053010210 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010211 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +053010212 hddLog(VOS_TRACE_LEVEL_INFO_MED,
10213 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010214 status = 0;
10215 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +053010216 }
10217 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
10218 {
10219 hddLog(VOS_TRACE_LEVEL_ERROR,
10220 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010221 status = -EINVAL;
10222 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070010223 }
10224#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070010225
10226 /* issue set key request to SME*/
10227 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
10228 pAdapter->sessionId, &setKey, &roamId );
10229
10230 if ( 0 != status )
10231 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010232 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010233 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
10234 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010235 status = -EINVAL;
10236 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070010237 }
10238
10239
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010240 /* in case of IBSS as there was no information available about WEP keys during
10241 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070010242 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010243 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
10244 !( ( IW_AUTH_KEY_MGMT_802_1X
10245 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070010246 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
10247 )
10248 &&
10249 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
10250 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
10251 )
10252 )
10253 {
10254 setKey.keyDirection = eSIR_RX_ONLY;
10255 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
10256
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010257 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070010258 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010259 __func__, setKey.peerMac[0], setKey.peerMac[1],
10260 setKey.peerMac[2], setKey.peerMac[3],
10261 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070010262 setKey.keyDirection);
10263
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010264 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010265 pAdapter->sessionId, &setKey, &roamId );
10266
10267 if ( 0 != status )
10268 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010269 hddLog(VOS_TRACE_LEVEL_ERROR,
10270 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010271 __func__, status);
10272 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010273 status = -EINVAL;
10274 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070010275 }
10276 }
10277 }
10278
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010279end:
10280 /* Need to clear any trace of key value in the memory.
10281 * Thus zero out the memory even though it is local
10282 * variable.
10283 */
10284 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010285 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010286 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010287}
10288
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010289#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10290static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
10291 struct net_device *ndev,
10292 u8 key_index, bool pairwise,
10293 const u8 *mac_addr,
10294 struct key_params *params
10295 )
10296#else
10297static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
10298 struct net_device *ndev,
10299 u8 key_index, const u8 *mac_addr,
10300 struct key_params *params
10301 )
10302#endif
10303{
10304 int ret;
10305 vos_ssr_protect(__func__);
10306#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10307 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
10308 mac_addr, params);
10309#else
10310 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
10311 params);
10312#endif
10313 vos_ssr_unprotect(__func__);
10314
10315 return ret;
10316}
10317
Jeff Johnson295189b2012-06-20 16:38:30 -070010318/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010319 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010320 * This function is used to get the key information
10321 */
10322#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010323static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010324 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010325 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010326 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070010327 const u8 *mac_addr, void *cookie,
10328 void (*callback)(void *cookie, struct key_params*)
10329 )
10330#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010331static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010332 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010333 struct net_device *ndev,
10334 u8 key_index, const u8 *mac_addr, void *cookie,
10335 void (*callback)(void *cookie, struct key_params*)
10336 )
10337#endif
10338{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010339 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010340 hdd_wext_state_t *pWextState = NULL;
10341 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010342 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010343 hdd_context_t *pHddCtx;
10344 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010345
10346 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010347
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010348 if (NULL == pAdapter)
10349 {
10350 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10351 "%s: HDD adapter is Null", __func__);
10352 return -ENODEV;
10353 }
10354
10355 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10356 ret = wlan_hdd_validate_context(pHddCtx);
10357 if (0 != ret)
10358 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010359 return ret;
10360 }
10361
10362 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10363 pRoamProfile = &(pWextState->roamProfile);
10364
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010365 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10366 __func__, hdd_device_modetoString(pAdapter->device_mode),
10367 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010368
Jeff Johnson295189b2012-06-20 16:38:30 -070010369 memset(&params, 0, sizeof(params));
10370
10371 if (CSR_MAX_NUM_KEY <= key_index)
10372 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010373 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070010374 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010375 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010376
10377 switch(pRoamProfile->EncryptionType.encryptionType[0])
10378 {
10379 case eCSR_ENCRYPT_TYPE_NONE:
10380 params.cipher = IW_AUTH_CIPHER_NONE;
10381 break;
10382
10383 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
10384 case eCSR_ENCRYPT_TYPE_WEP40:
10385 params.cipher = WLAN_CIPHER_SUITE_WEP40;
10386 break;
10387
10388 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
10389 case eCSR_ENCRYPT_TYPE_WEP104:
10390 params.cipher = WLAN_CIPHER_SUITE_WEP104;
10391 break;
10392
10393 case eCSR_ENCRYPT_TYPE_TKIP:
10394 params.cipher = WLAN_CIPHER_SUITE_TKIP;
10395 break;
10396
10397 case eCSR_ENCRYPT_TYPE_AES:
10398 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
10399 break;
10400
10401 default:
10402 params.cipher = IW_AUTH_CIPHER_NONE;
10403 break;
10404 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010405
c_hpothuaaf19692014-05-17 17:01:48 +053010406 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10407 TRACE_CODE_HDD_CFG80211_GET_KEY,
10408 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010409
Jeff Johnson295189b2012-06-20 16:38:30 -070010410 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
10411 params.seq_len = 0;
10412 params.seq = NULL;
10413 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
10414 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010415 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010416 return 0;
10417}
10418
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010419#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10420static int wlan_hdd_cfg80211_get_key(
10421 struct wiphy *wiphy,
10422 struct net_device *ndev,
10423 u8 key_index, bool pairwise,
10424 const u8 *mac_addr, void *cookie,
10425 void (*callback)(void *cookie, struct key_params*)
10426 )
10427#else
10428static int wlan_hdd_cfg80211_get_key(
10429 struct wiphy *wiphy,
10430 struct net_device *ndev,
10431 u8 key_index, const u8 *mac_addr, void *cookie,
10432 void (*callback)(void *cookie, struct key_params*)
10433 )
10434#endif
10435{
10436 int ret;
10437
10438 vos_ssr_protect(__func__);
10439#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10440 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
10441 mac_addr, cookie, callback);
10442#else
10443 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
10444 callback);
10445#endif
10446 vos_ssr_unprotect(__func__);
10447
10448 return ret;
10449}
10450
Jeff Johnson295189b2012-06-20 16:38:30 -070010451/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010452 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010453 * This function is used to delete the key information
10454 */
10455#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010456static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010457 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010458 u8 key_index,
10459 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070010460 const u8 *mac_addr
10461 )
10462#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010463static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010464 struct net_device *ndev,
10465 u8 key_index,
10466 const u8 *mac_addr
10467 )
10468#endif
10469{
10470 int status = 0;
10471
10472 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010473 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070010474 //it is observed that this is invalidating peer
10475 //key index whenever re-key is done. This is affecting data link.
10476 //It should be ok to ignore del_key.
10477#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010478 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
10479 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010480 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
10481 tCsrRoamSetKey setKey;
10482 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010483
Jeff Johnson295189b2012-06-20 16:38:30 -070010484 ENTER();
10485
10486 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
10487 __func__,pAdapter->device_mode);
10488
10489 if (CSR_MAX_NUM_KEY <= key_index)
10490 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010491 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010492 key_index);
10493
10494 return -EINVAL;
10495 }
10496
10497 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
10498 setKey.keyId = key_index;
10499
10500 if (mac_addr)
10501 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
10502 else
10503 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
10504
10505 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
10506
10507 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010508 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010509 )
10510 {
10511
10512 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070010513 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10514 if( pHostapdState->bssState == BSS_START)
10515 {
10516 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010517
Jeff Johnson295189b2012-06-20 16:38:30 -070010518 if ( status != eHAL_STATUS_SUCCESS )
10519 {
10520 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10521 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
10522 __LINE__, status );
10523 }
10524 }
10525 }
10526 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010527 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070010528 )
10529 {
10530 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10531
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010532 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
10533
10534 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070010535 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010536 __func__, setKey.peerMac[0], setKey.peerMac[1],
10537 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070010538 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010539 if(pAdapter->sessionCtx.station.conn_info.connState ==
10540 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070010541 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010542 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010543 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010544
Jeff Johnson295189b2012-06-20 16:38:30 -070010545 if ( 0 != status )
10546 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010547 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010548 "%s: sme_RoamSetKey failure, returned %d",
10549 __func__, status);
10550 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
10551 return -EINVAL;
10552 }
10553 }
10554 }
10555#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010556 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010557 return status;
10558}
10559
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010560#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10561static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
10562 struct net_device *ndev,
10563 u8 key_index,
10564 bool pairwise,
10565 const u8 *mac_addr
10566 )
10567#else
10568static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
10569 struct net_device *ndev,
10570 u8 key_index,
10571 const u8 *mac_addr
10572 )
10573#endif
10574{
10575 int ret;
10576
10577 vos_ssr_protect(__func__);
10578#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10579 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
10580 mac_addr);
10581#else
10582 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
10583#endif
10584 vos_ssr_unprotect(__func__);
10585
10586 return ret;
10587}
10588
Jeff Johnson295189b2012-06-20 16:38:30 -070010589/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010590 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010591 * This function is used to set the default tx key index
10592 */
10593#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010594static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010595 struct net_device *ndev,
10596 u8 key_index,
10597 bool unicast, bool multicast)
10598#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010599static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010600 struct net_device *ndev,
10601 u8 key_index)
10602#endif
10603{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010604 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010605 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010606 hdd_wext_state_t *pWextState;
10607 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010608 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010609
10610 ENTER();
10611
Gopichand Nakkala29149562013-05-10 21:43:41 +053010612 if ((NULL == pAdapter))
10613 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010615 "invalid adapter");
10616 return -EINVAL;
10617 }
10618
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010619 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10620 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
10621 pAdapter->sessionId, key_index));
10622
Gopichand Nakkala29149562013-05-10 21:43:41 +053010623 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10624 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10625
10626 if ((NULL == pWextState) || (NULL == pHddStaCtx))
10627 {
10628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10629 "invalid Wext state or HDD context");
10630 return -EINVAL;
10631 }
10632
Arif Hussain6d2a3322013-11-17 19:50:10 -080010633 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010634 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010635
Jeff Johnson295189b2012-06-20 16:38:30 -070010636 if (CSR_MAX_NUM_KEY <= key_index)
10637 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010638 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010639 key_index);
10640
10641 return -EINVAL;
10642 }
10643
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010644 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10645 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010646 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010647 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010648 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010649 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010650
Jeff Johnson295189b2012-06-20 16:38:30 -070010651 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010652 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010653 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010654 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053010655 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080010656 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010657 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080010658 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070010659 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010660 {
10661 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070010662 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010663
Jeff Johnson295189b2012-06-20 16:38:30 -070010664 tCsrRoamSetKey setKey;
10665 v_U32_t roamId= 0xFF;
10666 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010667
10668 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010669 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010670
Jeff Johnson295189b2012-06-20 16:38:30 -070010671 Keys->defaultIndex = (u8)key_index;
10672 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
10673 setKey.keyId = key_index;
10674 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010675
10676 vos_mem_copy(&setKey.Key[0],
10677 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010678 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010679
Gopichand Nakkala29149562013-05-10 21:43:41 +053010680 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010681
10682 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070010683 &pHddStaCtx->conn_info.bssId[0],
10684 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010685
Gopichand Nakkala29149562013-05-10 21:43:41 +053010686 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
10687 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
10688 eCSR_ENCRYPT_TYPE_WEP104)
10689 {
10690 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
10691 even though ap is configured for WEP-40 encryption. In this canse the key length
10692 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
10693 type(104) and switching encryption type to 40*/
10694 pWextState->roamProfile.EncryptionType.encryptionType[0] =
10695 eCSR_ENCRYPT_TYPE_WEP40;
10696 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
10697 eCSR_ENCRYPT_TYPE_WEP40;
10698 }
10699
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010700 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070010701 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010702
Jeff Johnson295189b2012-06-20 16:38:30 -070010703 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010704 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010705 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010706
Jeff Johnson295189b2012-06-20 16:38:30 -070010707 if ( 0 != status )
10708 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010709 hddLog(VOS_TRACE_LEVEL_ERROR,
10710 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010711 status);
10712 return -EINVAL;
10713 }
10714 }
10715 }
10716
10717 /* In SoftAp mode setting key direction for default mode */
10718 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
10719 {
10720 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
10721 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
10722 (eCSR_ENCRYPT_TYPE_AES !=
10723 pWextState->roamProfile.EncryptionType.encryptionType[0])
10724 )
10725 {
10726 /* Saving key direction for default key index to TX default */
10727 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
10728 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
10729 }
10730 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010731 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010732 return status;
10733}
10734
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010735#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10736static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
10737 struct net_device *ndev,
10738 u8 key_index,
10739 bool unicast, bool multicast)
10740#else
10741static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
10742 struct net_device *ndev,
10743 u8 key_index)
10744#endif
10745{
10746 int ret;
10747 vos_ssr_protect(__func__);
10748#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10749 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
10750 multicast);
10751#else
10752 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
10753#endif
10754 vos_ssr_unprotect(__func__);
10755
10756 return ret;
10757}
10758
Jeff Johnson295189b2012-06-20 16:38:30 -070010759/*
10760 * FUNCTION: wlan_hdd_cfg80211_inform_bss
10761 * This function is used to inform the BSS details to nl80211 interface.
10762 */
10763static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
10764 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
10765{
10766 struct net_device *dev = pAdapter->dev;
10767 struct wireless_dev *wdev = dev->ieee80211_ptr;
10768 struct wiphy *wiphy = wdev->wiphy;
10769 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
10770 int chan_no;
10771 int ie_length;
10772 const char *ie;
10773 unsigned int freq;
10774 struct ieee80211_channel *chan;
10775 int rssi = 0;
10776 struct cfg80211_bss *bss = NULL;
10777
Jeff Johnson295189b2012-06-20 16:38:30 -070010778 if( NULL == pBssDesc )
10779 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010780 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010781 return bss;
10782 }
10783
10784 chan_no = pBssDesc->channelId;
10785 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
10786 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
10787
10788 if( NULL == ie )
10789 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010790 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010791 return bss;
10792 }
10793
10794#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10795 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10796 {
10797 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10798 }
10799 else
10800 {
10801 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10802 }
10803#else
10804 freq = ieee80211_channel_to_frequency(chan_no);
10805#endif
10806
10807 chan = __ieee80211_get_channel(wiphy, freq);
10808
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053010809 if (!chan) {
10810 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
10811 return NULL;
10812 }
10813
Abhishek Singhaee43942014-06-16 18:55:47 +053010814 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070010815
Anand N Sunkad9f80b742015-07-30 20:05:51 +053010816 return cfg80211_inform_bss(wiphy, chan,
10817#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10818 CFG80211_BSS_FTYPE_UNKNOWN,
10819#endif
10820 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010821 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070010822 pBssDesc->capabilityInfo,
10823 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053010824 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070010825}
10826
10827
10828
10829/*
10830 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
10831 * This function is used to inform the BSS details to nl80211 interface.
10832 */
10833struct cfg80211_bss*
10834wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
10835 tSirBssDescription *bss_desc
10836 )
10837{
10838 /*
10839 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
10840 already exists in bss data base of cfg80211 for that particular BSS ID.
10841 Using cfg80211_inform_bss_frame to update the bss entry instead of
10842 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
10843 now there is no possibility to get the mgmt(probe response) frame from PE,
10844 converting bss_desc to ieee80211_mgmt(probe response) and passing to
10845 cfg80211_inform_bss_frame.
10846 */
10847 struct net_device *dev = pAdapter->dev;
10848 struct wireless_dev *wdev = dev->ieee80211_ptr;
10849 struct wiphy *wiphy = wdev->wiphy;
10850 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010851#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
10852 qcom_ie_age *qie_age = NULL;
10853 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
10854#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010855 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010856#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010857 const char *ie =
10858 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
10859 unsigned int freq;
10860 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053010861 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010862 struct cfg80211_bss *bss_status = NULL;
10863 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
10864 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070010865 hdd_context_t *pHddCtx;
10866 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070010867#ifdef WLAN_OPEN_SOURCE
10868 struct timespec ts;
10869#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010870
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010871
Wilson Yangf80a0542013-10-07 13:02:37 -070010872 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10873 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070010874 if (0 != status)
10875 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070010876 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010877 }
10878
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053010879 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070010880 if (!mgmt)
10881 {
10882 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10883 "%s: memory allocation failed ", __func__);
10884 return NULL;
10885 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070010886
Jeff Johnson295189b2012-06-20 16:38:30 -070010887 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070010888
10889#ifdef WLAN_OPEN_SOURCE
10890 /* Android does not want the timestamp from the frame.
10891 Instead it wants a monotonic increasing value */
10892 get_monotonic_boottime(&ts);
10893 mgmt->u.probe_resp.timestamp =
10894 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
10895#else
10896 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070010897 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
10898 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070010899
10900#endif
10901
Jeff Johnson295189b2012-06-20 16:38:30 -070010902 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
10903 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010904
10905#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
10906 /* GPS Requirement: need age ie per entry. Using vendor specific. */
10907 /* Assuming this is the last IE, copy at the end */
10908 ie_length -=sizeof(qcom_ie_age);
10909 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
10910 qie_age->element_id = QCOM_VENDOR_IE_ID;
10911 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
10912 qie_age->oui_1 = QCOM_OUI1;
10913 qie_age->oui_2 = QCOM_OUI2;
10914 qie_age->oui_3 = QCOM_OUI3;
10915 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
10916 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
10917#endif
10918
Jeff Johnson295189b2012-06-20 16:38:30 -070010919 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053010920 if (bss_desc->fProbeRsp)
10921 {
10922 mgmt->frame_control |=
10923 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
10924 }
10925 else
10926 {
10927 mgmt->frame_control |=
10928 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
10929 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010930
10931#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010932 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010933 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
10934 {
10935 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10936 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010937 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010938 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
10939
10940 {
10941 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10942 }
10943 else
10944 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010945 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
10946 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070010947 kfree(mgmt);
10948 return NULL;
10949 }
10950#else
10951 freq = ieee80211_channel_to_frequency(chan_no);
10952#endif
10953 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010954 /*when the band is changed on the fly using the GUI, three things are done
10955 * 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)
10956 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
10957 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
10958 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
10959 * and discards the channels correponding to previous band and calls back with zero bss results.
10960 * 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
10961 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
10962 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
10963 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
10964 * So drop the bss and continue to next bss.
10965 */
10966 if(chan == NULL)
10967 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010968 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070010969 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010970 return NULL;
10971 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053010972 /*To keep the rssi icon of the connected AP in the scan window
10973 *and the rssi icon of the wireless networks in sync
10974 * */
10975 if (( eConnectionState_Associated ==
10976 pAdapter->sessionCtx.station.conn_info.connState ) &&
10977 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
10978 pAdapter->sessionCtx.station.conn_info.bssId,
10979 WNI_CFG_BSSID_LEN)) &&
10980 (pHddCtx->hdd_wlan_suspended == FALSE))
10981 {
10982 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
10983 rssi = (pAdapter->rssi * 100);
10984 }
10985 else
10986 {
10987 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
10988 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010989
Nirav Shah20ac06f2013-12-12 18:14:06 +053010990 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053010991 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
10992 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053010993
Jeff Johnson295189b2012-06-20 16:38:30 -070010994 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
10995 frame_len, rssi, GFP_KERNEL);
10996 kfree(mgmt);
10997 return bss_status;
10998}
10999
11000/*
11001 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
11002 * This function is used to update the BSS data base of CFG8011
11003 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011004struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011005 tCsrRoamInfo *pRoamInfo
11006 )
11007{
11008 tCsrRoamConnectedProfile roamProfile;
11009 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
11010 struct cfg80211_bss *bss = NULL;
11011
11012 ENTER();
11013
11014 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
11015 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
11016
11017 if (NULL != roamProfile.pBssDesc)
11018 {
Girish Gowlif4b68022014-08-28 23:18:57 +053011019 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
11020 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070011021
11022 if (NULL == bss)
11023 {
11024 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
11025 __func__);
11026 }
11027
11028 sme_RoamFreeConnectProfile(hHal, &roamProfile);
11029 }
11030 else
11031 {
11032 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
11033 __func__);
11034 }
11035 return bss;
11036}
11037
11038/*
11039 * FUNCTION: wlan_hdd_cfg80211_update_bss
11040 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011041static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
11042 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070011043 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011044{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011045 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011046 tCsrScanResultInfo *pScanResult;
11047 eHalStatus status = 0;
11048 tScanResultHandle pResult;
11049 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070011050 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053011051 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070011052 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011053
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053011054 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11055 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
11056 NO_SESSION, pAdapter->sessionId));
11057
Wilson Yangf80a0542013-10-07 13:02:37 -070011058 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11059
11060 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070011061 {
Wilson Yangf80a0542013-10-07 13:02:37 -070011062 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
11063 "%s:LOGP in Progress. Ignore!!!",__func__);
11064 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070011065 }
11066
Wilson Yangf80a0542013-10-07 13:02:37 -070011067
11068 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053011069 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070011070 {
11071 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11072 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
11073 return VOS_STATUS_E_PERM;
11074 }
11075
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053011076 if (pAdapter->request != NULL)
11077 {
11078 if ((pAdapter->request->n_ssids == 1)
11079 && (pAdapter->request->ssids != NULL)
11080 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
11081 is_p2p_scan = true;
11082 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011083 /*
11084 * start getting scan results and populate cgf80211 BSS database
11085 */
11086 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
11087
11088 /* no scan results */
11089 if (NULL == pResult)
11090 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011091 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
11092 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053011093 wlan_hdd_get_frame_logs(pAdapter,
11094 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070011095 return status;
11096 }
11097
11098 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
11099
11100 while (pScanResult)
11101 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011102 /*
11103 * cfg80211_inform_bss() is not updating ie field of bss entry, if
11104 * entry already exists in bss data base of cfg80211 for that
11105 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
11106 * bss entry instead of cfg80211_inform_bss, But this call expects
11107 * mgmt packet as input. As of now there is no possibility to get
11108 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070011109 * ieee80211_mgmt(probe response) and passing to c
11110 * fg80211_inform_bss_frame.
11111 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053011112 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
11113 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
11114 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053011115 pScanResult = sme_ScanResultGetNext(hHal, pResult);
11116 continue; //Skip the non p2p bss entries
11117 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011118 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
11119 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011120
Jeff Johnson295189b2012-06-20 16:38:30 -070011121
11122 if (NULL == bss_status)
11123 {
11124 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011125 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011126 }
11127 else
11128 {
Yue Maf49ba872013-08-19 12:04:25 -070011129 cfg80211_put_bss(
11130#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
11131 wiphy,
11132#endif
11133 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070011134 }
11135
11136 pScanResult = sme_ScanResultGetNext(hHal, pResult);
11137 }
11138
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011139 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053011140 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011141 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011142}
11143
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011144void
11145hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
11146{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011147 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080011148 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011149} /****** end hddPrintMacAddr() ******/
11150
11151void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070011152hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011153{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011154 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080011155 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070011156 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
11157 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
11158 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011159} /****** end hddPrintPmkId() ******/
11160
11161//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
11162//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
11163
11164//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
11165//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
11166
11167#define dump_bssid(bssid) \
11168 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070011169 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
11170 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011171 }
11172
11173#define dump_pmkid(pMac, pmkid) \
11174 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070011175 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
11176 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011177 }
11178
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070011179#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011180/*
11181 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
11182 * This function is used to notify the supplicant of a new PMKSA candidate.
11183 */
11184int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011185 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011186 int index, bool preauth )
11187{
Jeff Johnsone7245742012-09-05 17:12:55 -070011188#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011189 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070011190 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011191
11192 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070011193 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011194
11195 if( NULL == pRoamInfo )
11196 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011197 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011198 return -EINVAL;
11199 }
11200
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070011201 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
11202 {
11203 dump_bssid(pRoamInfo->bssid);
11204 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011205 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070011206 }
Jeff Johnsone7245742012-09-05 17:12:55 -070011207#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011208 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070011209}
11210#endif //FEATURE_WLAN_LFR
11211
Yue Maef608272013-04-08 23:09:17 -070011212#ifdef FEATURE_WLAN_LFR_METRICS
11213/*
11214 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
11215 * 802.11r/LFR metrics reporting function to report preauth initiation
11216 *
11217 */
11218#define MAX_LFR_METRICS_EVENT_LENGTH 100
11219VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
11220 tCsrRoamInfo *pRoamInfo)
11221{
11222 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
11223 union iwreq_data wrqu;
11224
11225 ENTER();
11226
11227 if (NULL == pAdapter)
11228 {
11229 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
11230 return VOS_STATUS_E_FAILURE;
11231 }
11232
11233 /* create the event */
11234 memset(&wrqu, 0, sizeof(wrqu));
11235 memset(metrics_notification, 0, sizeof(metrics_notification));
11236
11237 wrqu.data.pointer = metrics_notification;
11238 wrqu.data.length = scnprintf(metrics_notification,
11239 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
11240 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
11241
11242 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
11243
11244 EXIT();
11245
11246 return VOS_STATUS_SUCCESS;
11247}
11248
11249/*
11250 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
11251 * 802.11r/LFR metrics reporting function to report preauth completion
11252 * or failure
11253 */
11254VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
11255 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
11256{
11257 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
11258 union iwreq_data wrqu;
11259
11260 ENTER();
11261
11262 if (NULL == pAdapter)
11263 {
11264 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
11265 return VOS_STATUS_E_FAILURE;
11266 }
11267
11268 /* create the event */
11269 memset(&wrqu, 0, sizeof(wrqu));
11270 memset(metrics_notification, 0, sizeof(metrics_notification));
11271
11272 scnprintf(metrics_notification, sizeof(metrics_notification),
11273 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
11274 MAC_ADDR_ARRAY(pRoamInfo->bssid));
11275
11276 if (1 == preauth_status)
11277 strncat(metrics_notification, " TRUE", 5);
11278 else
11279 strncat(metrics_notification, " FALSE", 6);
11280
11281 wrqu.data.pointer = metrics_notification;
11282 wrqu.data.length = strlen(metrics_notification);
11283
11284 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
11285
11286 EXIT();
11287
11288 return VOS_STATUS_SUCCESS;
11289}
11290
11291/*
11292 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
11293 * 802.11r/LFR metrics reporting function to report handover initiation
11294 *
11295 */
11296VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
11297 tCsrRoamInfo *pRoamInfo)
11298{
11299 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
11300 union iwreq_data wrqu;
11301
11302 ENTER();
11303
11304 if (NULL == pAdapter)
11305 {
11306 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
11307 return VOS_STATUS_E_FAILURE;
11308 }
11309
11310 /* create the event */
11311 memset(&wrqu, 0, sizeof(wrqu));
11312 memset(metrics_notification, 0, sizeof(metrics_notification));
11313
11314 wrqu.data.pointer = metrics_notification;
11315 wrqu.data.length = scnprintf(metrics_notification,
11316 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
11317 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
11318
11319 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
11320
11321 EXIT();
11322
11323 return VOS_STATUS_SUCCESS;
11324}
11325#endif
11326
Jeff Johnson295189b2012-06-20 16:38:30 -070011327/*
11328 * FUNCTION: hdd_cfg80211_scan_done_callback
11329 * scanning callback function, called after finishing scan
11330 *
11331 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011332static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070011333 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
11334{
11335 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011336 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070011337 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011338 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070011339 struct cfg80211_scan_request *req = NULL;
11340 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011341 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011342 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011343 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011344 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011345
11346 ENTER();
11347
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011348 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053011349 if (NULL == pHddCtx) {
11350 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011351 goto allow_suspend;
11352 }
11353
11354 pScanInfo = &pHddCtx->scan_info;
11355
Jeff Johnson295189b2012-06-20 16:38:30 -070011356 hddLog(VOS_TRACE_LEVEL_INFO,
11357 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080011358 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011359 __func__, halHandle, pContext, (int) scanId, (int) status);
11360
Kiet Lamac06e2c2013-10-23 16:25:07 +053011361 pScanInfo->mScanPendingCounter = 0;
11362
Jeff Johnson295189b2012-06-20 16:38:30 -070011363 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011364 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070011365 &pScanInfo->scan_req_completion_event,
11366 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011367 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070011368 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011369 hddLog(VOS_TRACE_LEVEL_ERROR,
11370 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070011371 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011372 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070011373 }
11374
Yue Maef608272013-04-08 23:09:17 -070011375 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070011376 {
11377 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011378 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070011379 }
11380
11381 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011382 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070011383 {
11384 hddLog(VOS_TRACE_LEVEL_INFO,
11385 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011386 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070011387 (int) scanId);
11388 }
11389
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011390 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011391 pAdapter);
11392
11393 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011394 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011395
11396
11397 /* If any client wait scan result through WEXT
11398 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011399 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070011400 {
11401 /* The other scan request waiting for current scan finish
11402 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011403 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070011404 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011405 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070011406 }
11407 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011408 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070011409 {
11410 struct net_device *dev = pAdapter->dev;
11411 union iwreq_data wrqu;
11412 int we_event;
11413 char *msg;
11414
11415 memset(&wrqu, '\0', sizeof(wrqu));
11416 we_event = SIOCGIWSCAN;
11417 msg = NULL;
11418 wireless_send_event(dev, we_event, &wrqu, msg);
11419 }
11420 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011421 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011422
11423 /* Get the Scan Req */
11424 req = pAdapter->request;
11425
11426 if (!req)
11427 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011428 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011429 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070011430 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070011431 }
11432
Jeff Johnson295189b2012-06-20 16:38:30 -070011433 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011434 /* Scan is no longer pending */
11435 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011436
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011437 /* last_scan_timestamp is used to decide if new scan
11438 * is needed or not on station interface. If last station
11439 * scan time and new station scan time is less then
11440 * last_scan_timestamp ; driver will return cached scan.
11441 */
11442 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
11443 {
11444 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
11445
11446 if ( req->n_channels )
11447 {
11448 for (i = 0; i < req->n_channels ; i++ )
11449 {
11450 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
11451 }
11452 /* store no of channel scanned */
11453 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
11454 }
11455
11456 }
11457
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070011458 /*
11459 * cfg80211_scan_done informing NL80211 about completion
11460 * of scanning
11461 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011462 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
11463 {
11464 aborted = true;
11465 }
11466 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080011467 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070011468
Siddharth Bhal76972212014-10-15 16:22:51 +053011469 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
11470 /* Generate new random mac addr for next scan */
11471 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
11472 hdd_processSpoofMacAddrRequest(pHddCtx);
11473 }
11474
Jeff Johnsone7245742012-09-05 17:12:55 -070011475allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011476 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011477 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011478
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070011479 /* Acquire wakelock to handle the case where APP's tries to suspend
11480 * immediatly after the driver gets connect request(i.e after scan)
11481 * from supplicant, this result in app's is suspending and not able
11482 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011483 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070011484
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070011485#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011486 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070011487#endif
11488
Jeff Johnson295189b2012-06-20 16:38:30 -070011489 EXIT();
11490 return 0;
11491}
11492
11493/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053011494 * FUNCTION: hdd_isConnectionInProgress
11495 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011496 *
11497 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011498v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011499{
11500 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11501 hdd_station_ctx_t *pHddStaCtx = NULL;
11502 hdd_adapter_t *pAdapter = NULL;
11503 VOS_STATUS status = 0;
11504 v_U8_t staId = 0;
11505 v_U8_t *staMac = NULL;
11506
c_hpothu9b781ba2013-12-30 20:57:45 +053011507 if (TRUE == pHddCtx->btCoexModeSet)
11508 {
11509 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053011510 FL("BTCoex Mode operation in progress"));
11511 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053011512 }
11513
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011514 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11515
11516 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11517 {
11518 pAdapter = pAdapterNode->pAdapter;
11519
11520 if( pAdapter )
11521 {
11522 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011523 "%s: Adapter with device mode %s (%d) exists",
11524 __func__, hdd_device_modetoString(pAdapter->device_mode),
11525 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011526 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053011527 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11528 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
11529 (eConnectionState_Connecting ==
11530 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
11531 {
11532 hddLog(VOS_TRACE_LEVEL_ERROR,
11533 "%s: %p(%d) Connection is in progress", __func__,
11534 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
11535 return VOS_TRUE;
11536 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011537 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053011538 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011539 {
11540 hddLog(VOS_TRACE_LEVEL_ERROR,
11541 "%s: %p(%d) Reassociation is in progress", __func__,
11542 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
11543 return VOS_TRUE;
11544 }
11545 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011546 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11547 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011548 {
11549 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11550 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011551 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011552 {
11553 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
11554 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080011555 "%s: client " MAC_ADDRESS_STR
11556 " is in the middle of WPS/EAPOL exchange.", __func__,
11557 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053011558 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011559 }
11560 }
11561 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
11562 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
11563 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011564 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11565 ptSapContext pSapCtx = NULL;
11566 pSapCtx = VOS_GET_SAP_CB(pVosContext);
11567 if(pSapCtx == NULL){
11568 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11569 FL("psapCtx is NULL"));
11570 return VOS_FALSE;
11571 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011572 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
11573 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011574 if ((pSapCtx->aStaInfo[staId].isUsed) &&
11575 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011576 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011577 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011578
11579 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080011580 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
11581 "middle of WPS/EAPOL exchange.", __func__,
11582 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053011583 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011584 }
11585 }
11586 }
11587 }
11588 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11589 pAdapterNode = pNext;
11590 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053011591 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011592}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011593
11594/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011595 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070011596 * this scan respond to scan trigger and update cfg80211 scan database
11597 * later, scan dump command can be used to recieve scan results
11598 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011599int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080011600#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11601 struct net_device *dev,
11602#endif
11603 struct cfg80211_scan_request *request)
11604{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011605 hdd_adapter_t *pAdapter = NULL;
11606 hdd_context_t *pHddCtx = NULL;
11607 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011608 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011609 tCsrScanRequest scanRequest;
11610 tANI_U8 *channelList = NULL, i;
11611 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011612 int status;
11613 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011614 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011615 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053011616 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011617 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053011618 v_S7_t rssi=0;
11619 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011620
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011621#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
11622 struct net_device *dev = NULL;
11623 if (NULL == request)
11624 {
11625 hddLog(VOS_TRACE_LEVEL_ERROR,
11626 "%s: scan req param null", __func__);
11627 return -EINVAL;
11628 }
11629 dev = request->wdev->netdev;
11630#endif
11631
11632 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11633 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
11634 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11635
Jeff Johnson295189b2012-06-20 16:38:30 -070011636 ENTER();
11637
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011638 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11639 __func__, hdd_device_modetoString(pAdapter->device_mode),
11640 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011641
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011642 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011643 if (0 != status)
11644 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011645 return status;
11646 }
11647
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011648 if (NULL == pwextBuf)
11649 {
11650 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
11651 __func__);
11652 return -EIO;
11653 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011654 cfg_param = pHddCtx->cfg_ini;
11655 pScanInfo = &pHddCtx->scan_info;
11656
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053011657 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11658 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
11659 {
11660 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
11661 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
11662 }
11663
Jeff Johnson295189b2012-06-20 16:38:30 -070011664#ifdef WLAN_BTAMP_FEATURE
11665 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011666 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070011667 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011668 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011669 "%s: No scanning when AMP is on", __func__);
11670 return -EOPNOTSUPP;
11671 }
11672#endif
11673 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011674 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011675 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011676 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011677 "%s: Not scanning on device_mode = %s (%d)",
11678 __func__, hdd_device_modetoString(pAdapter->device_mode),
11679 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011680 return -EOPNOTSUPP;
11681 }
11682
11683 if (TRUE == pScanInfo->mScanPending)
11684 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053011685 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
11686 {
11687 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
11688 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011689 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070011690 }
11691
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053011692 // Don't allow scan if PNO scan is going on.
11693 if (pHddCtx->isPnoEnable)
11694 {
11695 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11696 FL("pno scan in progress"));
11697 return -EBUSY;
11698 }
11699
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011700 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070011701 //Channel and action frame is pending
11702 //Otherwise Cancel Remain On Channel and allow Scan
11703 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011704 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070011705 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053011706 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070011707 return -EBUSY;
11708 }
11709
Jeff Johnson295189b2012-06-20 16:38:30 -070011710 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
11711 {
11712 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080011713 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011714 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011715 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011716 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
11717 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011718 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011719 "%s: MAX TM Level Scan not allowed", __func__);
11720 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011721 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070011722 }
11723 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
11724
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011725 /* Check if scan is allowed at this point of time.
11726 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011727 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011728 {
11729 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
11730 return -EBUSY;
11731 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011732
Jeff Johnson295189b2012-06-20 16:38:30 -070011733 vos_mem_zero( &scanRequest, sizeof(scanRequest));
11734
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011735 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
11736 * Becasue of this, driver is assuming that this is not wildcard scan and so
11737 * is not aging out the scan results.
11738 */
11739 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011740 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011741 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011742 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011743
11744 if ((request->ssids) && (0 < request->n_ssids))
11745 {
11746 tCsrSSIDInfo *SsidInfo;
11747 int j;
11748 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
11749 /* Allocate num_ssid tCsrSSIDInfo structure */
11750 SsidInfo = scanRequest.SSIDs.SSIDList =
11751 ( tCsrSSIDInfo *)vos_mem_malloc(
11752 request->n_ssids*sizeof(tCsrSSIDInfo));
11753
11754 if(NULL == scanRequest.SSIDs.SSIDList)
11755 {
11756 hddLog(VOS_TRACE_LEVEL_ERROR,
11757 "%s: memory alloc failed SSIDInfo buffer", __func__);
11758 return -ENOMEM;
11759 }
11760
11761 /* copy all the ssid's and their length */
11762 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
11763 {
11764 /* get the ssid length */
11765 SsidInfo->SSID.length = request->ssids[j].ssid_len;
11766 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
11767 SsidInfo->SSID.length);
11768 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
11769 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
11770 j, SsidInfo->SSID.ssId);
11771 }
11772 /* set the scan type to active */
11773 scanRequest.scanType = eSIR_ACTIVE_SCAN;
11774 }
11775 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011776 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011777 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11778 TRACE_CODE_HDD_CFG80211_SCAN,
11779 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070011780 /* set the scan type to active */
11781 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070011782 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011783 else
11784 {
11785 /*Set the scan type to default type, in this case it is ACTIVE*/
11786 scanRequest.scanType = pScanInfo->scan_mode;
11787 }
11788 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
11789 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070011790
11791 /* set BSSType to default type */
11792 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
11793
11794 /*TODO: scan the requested channels only*/
11795
11796 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011797 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070011798 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011799 hddLog(VOS_TRACE_LEVEL_WARN,
11800 "No of Scan Channels exceeded limit: %d", request->n_channels);
11801 request->n_channels = MAX_CHANNEL;
11802 }
11803
11804 hddLog(VOS_TRACE_LEVEL_INFO,
11805 "No of Scan Channels: %d", request->n_channels);
11806
11807
11808 if( request->n_channels )
11809 {
11810 char chList [(request->n_channels*5)+1];
11811 int len;
11812 channelList = vos_mem_malloc( request->n_channels );
11813 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053011814 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011815 hddLog(VOS_TRACE_LEVEL_ERROR,
11816 "%s: memory alloc failed channelList", __func__);
11817 status = -ENOMEM;
11818 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053011819 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011820
11821 for( i = 0, len = 0; i < request->n_channels ; i++ )
11822 {
11823 channelList[i] = request->channels[i]->hw_value;
11824 len += snprintf(chList+len, 5, "%d ", channelList[i]);
11825 }
11826
Nirav Shah20ac06f2013-12-12 18:14:06 +053011827 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011828 "Channel-List: %s ", chList);
11829 }
c_hpothu53512302014-04-15 18:49:53 +053011830
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011831 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
11832 scanRequest.ChannelInfo.ChannelList = channelList;
11833
11834 /* set requestType to full scan */
11835 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
11836
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011837 /* if there is back to back scan happening in driver with in
11838 * nDeferScanTimeInterval interval driver should defer new scan request
11839 * and should provide last cached scan results instead of new channel list.
11840 * This rule is not applicable if scan is p2p scan.
11841 * This condition will work only in case when last request no of channels
11842 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053011843 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053011844 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011845 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011846
Sushant Kaushik86592172015-04-27 16:35:03 +053011847 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
11848 /* if wps ie is NULL , then only defer scan */
11849 if ( pWpsIe == NULL &&
11850 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053011851 {
11852 if ( pScanInfo->last_scan_timestamp !=0 &&
11853 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
11854 {
11855 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
11856 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
11857 vos_mem_compare(pScanInfo->last_scan_channelList,
11858 channelList, pScanInfo->last_scan_numChannels))
11859 {
11860 hddLog(VOS_TRACE_LEVEL_WARN,
11861 " New and old station scan time differ is less then %u",
11862 pHddCtx->cfg_ini->nDeferScanTimeInterval);
11863
11864 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011865 pAdapter);
11866
Agarwal Ashish57e84372014-12-05 18:26:53 +053011867 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053011868 "Return old cached scan as all channels and no of channels are same");
11869
Agarwal Ashish57e84372014-12-05 18:26:53 +053011870 if (0 > ret)
11871 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011872
Agarwal Ashish57e84372014-12-05 18:26:53 +053011873 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053011874
11875 status = eHAL_STATUS_SUCCESS;
11876 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053011877 }
11878 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011879 }
11880
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011881 /* Flush the scan results(only p2p beacons) for STA scan and P2P
11882 * search (Flush on both full scan and social scan but not on single
11883 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
11884 */
11885
11886 /* Supplicant does single channel scan after 8-way handshake
11887 * and in that case driver shoudnt flush scan results. If
11888 * driver flushes the scan results here and unfortunately if
11889 * the AP doesnt respond to our probe req then association
11890 * fails which is not desired
11891 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011892 if ((request->n_ssids == 1)
11893 && (request->ssids != NULL)
11894 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
11895 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011896
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011897 if( is_p2p_scan ||
11898 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011899 {
11900 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
11901 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
11902 pAdapter->sessionId );
11903 }
11904
11905 if( request->ie_len )
11906 {
11907 /* save this for future association (join requires this) */
11908 /*TODO: Array needs to be converted to dynamic allocation,
11909 * as multiple ie.s can be sent in cfg80211_scan_request structure
11910 * CR 597966
11911 */
11912 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
11913 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
11914 pScanInfo->scanAddIE.length = request->ie_len;
11915
11916 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11917 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11918 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011919 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011920 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070011921 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011922 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
11923 memcpy( pwextBuf->roamProfile.addIEScan,
11924 request->ie, request->ie_len);
11925 }
11926 else
11927 {
11928 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
11929 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011930 }
11931
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011932 }
11933 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
11934 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
11935
11936 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
11937 request->ie_len);
11938 if (pP2pIe != NULL)
11939 {
11940#ifdef WLAN_FEATURE_P2P_DEBUG
11941 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
11942 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
11943 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053011944 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011945 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
11946 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11947 "Go nego completed to Connection is started");
11948 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11949 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053011950 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011951 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
11952 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011953 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011954 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
11955 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11956 "Disconnected state to Connection is started");
11957 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11958 "for 4way Handshake");
11959 }
11960#endif
11961
11962 /* no_cck will be set during p2p find to disable 11b rates */
11963 if(TRUE == request->no_cck)
11964 {
11965 hddLog(VOS_TRACE_LEVEL_INFO,
11966 "%s: This is a P2P Search", __func__);
11967 scanRequest.p2pSearch = 1;
11968
11969 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053011970 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011971 /* set requestType to P2P Discovery */
11972 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
11973 }
11974
11975 /*
11976 Skip Dfs Channel in case of P2P Search
11977 if it is set in ini file
11978 */
11979 if(cfg_param->skipDfsChnlInP2pSearch)
11980 {
11981 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011982 }
11983 else
11984 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011985 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011986 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011987
Agarwal Ashish4f616132013-12-30 23:32:50 +053011988 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011989 }
11990 }
11991
11992 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
11993
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011994#ifdef FEATURE_WLAN_TDLS
11995 /* if tdls disagree scan right now, return immediately.
11996 tdls will schedule the scan when scan is allowed. (return SUCCESS)
11997 or will reject the scan if any TDLS is in progress. (return -EBUSY)
11998 */
11999 status = wlan_hdd_tdls_scan_callback (pAdapter,
12000 wiphy,
12001#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12002 dev,
12003#endif
12004 request);
12005 if(status <= 0)
12006 {
12007 if(!status)
12008 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
12009 "scan rejected %d", __func__, status);
12010 else
12011 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
12012 __func__, status);
12013
12014 return status;
12015 }
12016#endif
12017
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070012018 /* acquire the wakelock to avoid the apps suspend during the scan. To
12019 * address the following issues.
12020 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
12021 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
12022 * for long time, this result in apps running at full power for long time.
12023 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
12024 * be stuck in full power because of resume BMPS
12025 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012026 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070012027
Nirav Shah20ac06f2013-12-12 18:14:06 +053012028 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
12029 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012030 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
12031 scanRequest.requestType, scanRequest.scanType,
12032 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053012033 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
12034
Siddharth Bhal76972212014-10-15 16:22:51 +053012035 if (pHddCtx->spoofMacAddr.isEnabled)
12036 {
12037 hddLog(VOS_TRACE_LEVEL_INFO,
12038 "%s: MAC Spoofing enabled for current scan", __func__);
12039 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
12040 * to fill TxBds for probe request during current scan
12041 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053012042 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053012043 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053012044
12045 if(status != VOS_STATUS_SUCCESS)
12046 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012047 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053012048 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053012049#ifdef FEATURE_WLAN_TDLS
12050 wlan_hdd_tdls_scan_done_callback(pAdapter);
12051#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053012052 goto free_mem;
12053 }
Siddharth Bhal76972212014-10-15 16:22:51 +053012054 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053012055 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070012056 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012057 pAdapter->sessionId, &scanRequest, &scanId,
12058 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070012059
Jeff Johnson295189b2012-06-20 16:38:30 -070012060 if (eHAL_STATUS_SUCCESS != status)
12061 {
12062 hddLog(VOS_TRACE_LEVEL_ERROR,
12063 "%s: sme_ScanRequest returned error %d", __func__, status);
12064 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070012065 if(eHAL_STATUS_RESOURCES == status)
12066 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053012067 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
12068 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070012069 status = -EBUSY;
12070 } else {
12071 status = -EIO;
12072 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053012073 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053012074
12075#ifdef FEATURE_WLAN_TDLS
12076 wlan_hdd_tdls_scan_done_callback(pAdapter);
12077#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012078 goto free_mem;
12079 }
12080
12081 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012082 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070012083 pAdapter->request = request;
12084 pScanInfo->scanId = scanId;
12085
12086 complete(&pScanInfo->scan_req_completion_event);
12087
12088free_mem:
12089 if( scanRequest.SSIDs.SSIDList )
12090 {
12091 vos_mem_free(scanRequest.SSIDs.SSIDList);
12092 }
12093
12094 if( channelList )
12095 vos_mem_free( channelList );
12096
12097 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012098 return status;
12099}
12100
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012101int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
12102#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12103 struct net_device *dev,
12104#endif
12105 struct cfg80211_scan_request *request)
12106{
12107 int ret;
12108
12109 vos_ssr_protect(__func__);
12110 ret = __wlan_hdd_cfg80211_scan(wiphy,
12111#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
12112 dev,
12113#endif
12114 request);
12115 vos_ssr_unprotect(__func__);
12116
12117 return ret;
12118}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012119
12120void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
12121{
12122 v_U8_t iniDot11Mode =
12123 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
12124 eHddDot11Mode hddDot11Mode = iniDot11Mode;
12125
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012126 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
12127 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012128 switch ( iniDot11Mode )
12129 {
12130 case eHDD_DOT11_MODE_AUTO:
12131 case eHDD_DOT11_MODE_11ac:
12132 case eHDD_DOT11_MODE_11ac_ONLY:
12133#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053012134 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
12135 sme_IsFeatureSupportedByFW(DOT11AC) )
12136 hddDot11Mode = eHDD_DOT11_MODE_11ac;
12137 else
12138 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012139#else
12140 hddDot11Mode = eHDD_DOT11_MODE_11n;
12141#endif
12142 break;
12143 case eHDD_DOT11_MODE_11n:
12144 case eHDD_DOT11_MODE_11n_ONLY:
12145 hddDot11Mode = eHDD_DOT11_MODE_11n;
12146 break;
12147 default:
12148 hddDot11Mode = iniDot11Mode;
12149 break;
12150 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053012151#ifdef WLAN_FEATURE_AP_HT40_24G
12152 if (operationChannel > SIR_11B_CHANNEL_END)
12153#endif
12154 {
12155 /* This call decides required channel bonding mode */
12156 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012157 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
12158 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053012159 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012160}
12161
Jeff Johnson295189b2012-06-20 16:38:30 -070012162/*
12163 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012164 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070012165 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012166int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053012167 const u8 *ssid, size_t ssid_len, const u8 *bssid,
12168 const u8 *bssid_hint, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070012169{
12170 int status = 0;
12171 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080012172 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012173 v_U32_t roamId;
12174 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070012175 eCsrAuthType RSNAuthType;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053012176 const u8 *pValidBssid = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012177
12178 ENTER();
12179
12180 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080012181 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12182
12183 status = wlan_hdd_validate_context(pHddCtx);
12184 if (status)
12185 {
Yue Mae36e3552014-03-05 17:06:20 -080012186 return status;
12187 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012188
Jeff Johnson295189b2012-06-20 16:38:30 -070012189 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
12190 {
12191 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
12192 return -EINVAL;
12193 }
12194
12195 pRoamProfile = &pWextState->roamProfile;
12196
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012197 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070012198 {
Jeff Johnsone7245742012-09-05 17:12:55 -070012199 hdd_station_ctx_t *pHddStaCtx;
12200 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012201
Siddharth Bhalda0d1622015-04-24 15:47:49 +053012202 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
12203
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012204 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070012205 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
12206 {
12207 /*QoS not enabled in cfg file*/
12208 pRoamProfile->uapsd_mask = 0;
12209 }
12210 else
12211 {
12212 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012213 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070012214 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
12215 }
12216
12217 pRoamProfile->SSIDs.numOfSSIDs = 1;
12218 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
12219 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012220 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070012221 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
12222 ssid, ssid_len);
12223
12224 if (bssid)
12225 {
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053012226 pValidBssid = bssid;
12227 }
12228 else if (bssid_hint)
12229 {
12230 pValidBssid = bssid_hint;
12231 }
12232 if (pValidBssid)
12233 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012234 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053012235 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070012236 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012237 /* Save BSSID in seperate variable as well, as RoamProfile
12238 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070012239 case of join failure we should send valid BSSID to supplicant
12240 */
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053012241 vos_mem_copy((void *)(pWextState->req_bssId), pValidBssid,
Jeff Johnson295189b2012-06-20 16:38:30 -070012242 WNI_CFG_BSSID_LEN);
12243 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070012244 else
12245 {
12246 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
12247 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012248
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012249 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
12250 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070012251 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
12252 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012253 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012254 /*set gen ie*/
12255 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
12256 /*set auth*/
12257 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
12258 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012259#ifdef FEATURE_WLAN_WAPI
12260 if (pAdapter->wapi_info.nWapiMode)
12261 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012262 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012263 switch (pAdapter->wapi_info.wapiAuthMode)
12264 {
12265 case WAPI_AUTH_MODE_PSK:
12266 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012267 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012268 pAdapter->wapi_info.wapiAuthMode);
12269 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
12270 break;
12271 }
12272 case WAPI_AUTH_MODE_CERT:
12273 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012274 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012275 pAdapter->wapi_info.wapiAuthMode);
12276 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
12277 break;
12278 }
12279 } // End of switch
12280 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
12281 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
12282 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012283 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012284 pRoamProfile->AuthType.numEntries = 1;
12285 pRoamProfile->EncryptionType.numEntries = 1;
12286 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
12287 pRoamProfile->mcEncryptionType.numEntries = 1;
12288 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
12289 }
12290 }
12291#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053012292#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053012293 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053012294 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
12295 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
12296 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053012297 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
12298 sizeof (tSirGtkOffloadParams));
12299 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053012300 }
12301#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012302 pRoamProfile->csrPersona = pAdapter->device_mode;
12303
Jeff Johnson32d95a32012-09-10 13:15:23 -070012304 if( operatingChannel )
12305 {
12306 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
12307 pRoamProfile->ChannelInfo.numOfChannels = 1;
12308 }
Chet Lanctot186b5732013-03-18 10:26:30 -070012309 else
12310 {
12311 pRoamProfile->ChannelInfo.ChannelList = NULL;
12312 pRoamProfile->ChannelInfo.numOfChannels = 0;
12313 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012314 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
12315 {
12316 hdd_select_cbmode(pAdapter,operatingChannel);
12317 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012318
Agarwal Ashish40f9b872015-09-01 16:17:35 +053012319 /*
12320 * Change conn_state to connecting before sme_RoamConnect(),
12321 * because sme_RoamConnect() has a direct path to call
12322 * hdd_smeRoamCallback(), which will change the conn_state
12323 * If direct path, conn_state will be accordingly changed
12324 * to NotConnected or Associated by either
12325 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
12326 * in sme_RoamCallback()
12327 * if sme_RomConnect is to be queued,
12328 * Connecting state will remain until it is completed.
12329 * If connection state is not changed,
12330 * connection state will remain in eConnectionState_NotConnected state.
12331 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
12332 * if conn state is eConnectionState_NotConnected.
12333 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
12334 * informed of connect result indication which is an issue.
12335 */
12336
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053012337 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
12338 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053012339 {
12340 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053012341 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080012342 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
12343 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053012344 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012345 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012346 pAdapter->sessionId, pRoamProfile, &roamId);
12347
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053012348 if ((eHAL_STATUS_SUCCESS != status) &&
12349 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
12350 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053012351
12352 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053012353 hddLog(VOS_TRACE_LEVEL_ERROR,
12354 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
12355 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080012356 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053012357 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080012358 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053012359 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080012360
12361 pRoamProfile->ChannelInfo.ChannelList = NULL;
12362 pRoamProfile->ChannelInfo.numOfChannels = 0;
12363
Jeff Johnson295189b2012-06-20 16:38:30 -070012364 }
12365 else
12366 {
12367 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
12368 return -EINVAL;
12369 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080012370 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012371 return status;
12372}
12373
12374/*
12375 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
12376 * This function is used to set the authentication type (OPEN/SHARED).
12377 *
12378 */
12379static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
12380 enum nl80211_auth_type auth_type)
12381{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012382 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012383 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12384
12385 ENTER();
12386
12387 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012388 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070012389 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012390 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012391 hddLog(VOS_TRACE_LEVEL_INFO,
12392 "%s: set authentication type to AUTOSWITCH", __func__);
12393 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
12394 break;
12395
12396 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012397#ifdef WLAN_FEATURE_VOWIFI_11R
12398 case NL80211_AUTHTYPE_FT:
12399#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012400 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070012401 "%s: set authentication type to OPEN", __func__);
12402 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
12403 break;
12404
12405 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012406 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070012407 "%s: set authentication type to SHARED", __func__);
12408 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
12409 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012410#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012411 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012412 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070012413 "%s: set authentication type to CCKM WPA", __func__);
12414 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
12415 break;
12416#endif
12417
12418
12419 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012420 hddLog(VOS_TRACE_LEVEL_ERROR,
12421 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012422 auth_type);
12423 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
12424 return -EINVAL;
12425 }
12426
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012427 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012428 pHddStaCtx->conn_info.authType;
12429 return 0;
12430}
12431
12432/*
12433 * FUNCTION: wlan_hdd_set_akm_suite
12434 * This function is used to set the key mgmt type(PSK/8021x).
12435 *
12436 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012437static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012438 u32 key_mgmt
12439 )
12440{
12441 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12442 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053012443 /* Should be in ieee802_11_defs.h */
12444#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
12445#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070012446 /*set key mgmt type*/
12447 switch(key_mgmt)
12448 {
12449 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053012450 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012451#ifdef WLAN_FEATURE_VOWIFI_11R
12452 case WLAN_AKM_SUITE_FT_PSK:
12453#endif
12454 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070012455 __func__);
12456 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
12457 break;
12458
12459 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053012460 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012461#ifdef WLAN_FEATURE_VOWIFI_11R
12462 case WLAN_AKM_SUITE_FT_8021X:
12463#endif
12464 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070012465 __func__);
12466 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
12467 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012468#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012469#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
12470#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
12471 case WLAN_AKM_SUITE_CCKM:
12472 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
12473 __func__);
12474 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
12475 break;
12476#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070012477#ifndef WLAN_AKM_SUITE_OSEN
12478#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
12479 case WLAN_AKM_SUITE_OSEN:
12480 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
12481 __func__);
12482 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
12483 break;
12484#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012485
12486 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012487 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012488 __func__, key_mgmt);
12489 return -EINVAL;
12490
12491 }
12492 return 0;
12493}
12494
12495/*
12496 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012497 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070012498 * (NONE/WEP40/WEP104/TKIP/CCMP).
12499 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012500static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
12501 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070012502 bool ucast
12503 )
12504{
12505 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012506 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012507 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12508
12509 ENTER();
12510
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012511 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012512 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012513 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070012514 __func__, cipher);
12515 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12516 }
12517 else
12518 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012519
Jeff Johnson295189b2012-06-20 16:38:30 -070012520 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012521 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012522 {
12523 case IW_AUTH_CIPHER_NONE:
12524 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12525 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012526
Jeff Johnson295189b2012-06-20 16:38:30 -070012527 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012528 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070012529 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012530
Jeff Johnson295189b2012-06-20 16:38:30 -070012531 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012532 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070012533 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012534
Jeff Johnson295189b2012-06-20 16:38:30 -070012535 case WLAN_CIPHER_SUITE_TKIP:
12536 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
12537 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012538
Jeff Johnson295189b2012-06-20 16:38:30 -070012539 case WLAN_CIPHER_SUITE_CCMP:
12540 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12541 break;
12542#ifdef FEATURE_WLAN_WAPI
12543 case WLAN_CIPHER_SUITE_SMS4:
12544 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
12545 break;
12546#endif
12547
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012548#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012549 case WLAN_CIPHER_SUITE_KRK:
12550 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
12551 break;
12552#endif
12553 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012554 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012555 __func__, cipher);
12556 return -EOPNOTSUPP;
12557 }
12558 }
12559
12560 if (ucast)
12561 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012562 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012563 __func__, encryptionType);
12564 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12565 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012566 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012567 encryptionType;
12568 }
12569 else
12570 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012571 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012572 __func__, encryptionType);
12573 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
12574 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
12575 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
12576 }
12577
12578 return 0;
12579}
12580
12581
12582/*
12583 * FUNCTION: wlan_hdd_cfg80211_set_ie
12584 * This function is used to parse WPA/RSN IE's.
12585 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012586int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012587#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12588 const u8 *ie,
12589#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012590 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012591#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012592 size_t ie_len
12593 )
12594{
12595 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012596#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12597 const u8 *genie = ie;
12598#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012599 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012600#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012601 v_U16_t remLen = ie_len;
12602#ifdef FEATURE_WLAN_WAPI
12603 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
12604 u16 *tmp;
12605 v_U16_t akmsuiteCount;
12606 int *akmlist;
12607#endif
12608 ENTER();
12609
12610 /* clear previous assocAddIE */
12611 pWextState->assocAddIE.length = 0;
12612 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012613 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012614
12615 while (remLen >= 2)
12616 {
12617 v_U16_t eLen = 0;
12618 v_U8_t elementId;
12619 elementId = *genie++;
12620 eLen = *genie++;
12621 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012622
Arif Hussain6d2a3322013-11-17 19:50:10 -080012623 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070012624 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012625
12626 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070012627 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012628 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012629 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 -070012630 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012631 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012632 "%s: Invalid WPA IE", __func__);
12633 return -EINVAL;
12634 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012635 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070012636 {
12637 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012638 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012639 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012640
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012641 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012642 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012643 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
12644 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012645 VOS_ASSERT(0);
12646 return -ENOMEM;
12647 }
12648 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
12649 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12650 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012651
Jeff Johnson295189b2012-06-20 16:38:30 -070012652 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
12653 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12654 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12655 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012656 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
12657 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012658 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
12659 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
12660 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
12661 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
12662 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
12663 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012664 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053012665 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070012666 {
12667 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012668 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012669 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012670
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012671 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012672 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012673 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12674 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012675 VOS_ASSERT(0);
12676 return -ENOMEM;
12677 }
12678 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
12679 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12680 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012681
Jeff Johnson295189b2012-06-20 16:38:30 -070012682 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12683 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12684 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012685#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012686 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
12687 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012688 /*Consider WFD IE, only for P2P Client */
12689 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
12690 {
12691 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012692 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012693 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012694
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012695 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012696 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012697 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12698 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012699 VOS_ASSERT(0);
12700 return -ENOMEM;
12701 }
12702 // WFD IE is saved to Additional IE ; it should be accumulated to handle
12703 // WPS IE + P2P IE + WFD IE
12704 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12705 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012706
Jeff Johnson295189b2012-06-20 16:38:30 -070012707 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12708 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12709 }
12710#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012711 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012712 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012713 HS20_OUI_TYPE_SIZE)) )
12714 {
12715 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012716 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012717 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012718
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012719 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012720 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012721 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12722 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012723 VOS_ASSERT(0);
12724 return -ENOMEM;
12725 }
12726 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12727 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012728
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012729 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12730 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12731 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012732 /* Appending OSEN Information Element in Assiciation Request */
12733 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
12734 OSEN_OUI_TYPE_SIZE)) )
12735 {
12736 v_U16_t curAddIELen = pWextState->assocAddIE.length;
12737 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
12738 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012739
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012740 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012741 {
12742 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12743 "Need bigger buffer space");
12744 VOS_ASSERT(0);
12745 return -ENOMEM;
12746 }
12747 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12748 pWextState->assocAddIE.length += eLen + 2;
12749
12750 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
12751 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12752 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12753 }
12754
Abhishek Singh4322e622015-06-10 15:42:54 +053012755 /* Update only for WPA IE */
12756 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
12757 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070012758
12759 /* populating as ADDIE in beacon frames */
12760 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012761 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070012762 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
12763 {
12764 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
12765 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
12766 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
12767 {
12768 hddLog(LOGE,
12769 "Coldn't pass "
12770 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
12771 }
12772 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
12773 else
12774 hddLog(LOGE,
12775 "Could not pass on "
12776 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
12777
12778 /* IBSS mode doesn't contain params->proberesp_ies still
12779 beaconIE's need to be populated in probe response frames */
12780 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
12781 {
12782 u16 rem_probe_resp_ie_len = eLen + 2;
12783 u8 probe_rsp_ie_len[3] = {0};
12784 u8 counter = 0;
12785
12786 /* Check Probe Resp Length if it is greater then 255 then
12787 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
12788 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
12789 not able Store More then 255 bytes into One Variable */
12790
12791 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
12792 {
12793 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
12794 {
12795 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
12796 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
12797 }
12798 else
12799 {
12800 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
12801 rem_probe_resp_ie_len = 0;
12802 }
12803 }
12804
12805 rem_probe_resp_ie_len = 0;
12806
12807 if (probe_rsp_ie_len[0] > 0)
12808 {
12809 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12810 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
12811 (tANI_U8*)(genie - 2),
12812 probe_rsp_ie_len[0], NULL,
12813 eANI_BOOLEAN_FALSE)
12814 == eHAL_STATUS_FAILURE)
12815 {
12816 hddLog(LOGE,
12817 "Could not pass"
12818 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
12819 }
12820 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
12821 }
12822
12823 if (probe_rsp_ie_len[1] > 0)
12824 {
12825 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12826 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
12827 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
12828 probe_rsp_ie_len[1], NULL,
12829 eANI_BOOLEAN_FALSE)
12830 == eHAL_STATUS_FAILURE)
12831 {
12832 hddLog(LOGE,
12833 "Could not pass"
12834 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
12835 }
12836 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
12837 }
12838
12839 if (probe_rsp_ie_len[2] > 0)
12840 {
12841 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12842 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
12843 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
12844 probe_rsp_ie_len[2], NULL,
12845 eANI_BOOLEAN_FALSE)
12846 == eHAL_STATUS_FAILURE)
12847 {
12848 hddLog(LOGE,
12849 "Could not pass"
12850 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
12851 }
12852 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
12853 }
12854
12855 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
12856 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
12857 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
12858 {
12859 hddLog(LOGE,
12860 "Could not pass"
12861 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
12862 }
12863 }
12864 else
12865 {
12866 // Reset WNI_CFG_PROBE_RSP Flags
12867 wlan_hdd_reset_prob_rspies(pAdapter);
12868
12869 hddLog(VOS_TRACE_LEVEL_INFO,
12870 "%s: No Probe Response IE received in set beacon",
12871 __func__);
12872 }
12873 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012874 break;
12875 case DOT11F_EID_RSN:
12876 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
12877 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
12878 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
12879 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
12880 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
12881 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053012882
12883 /* Appending Extended Capabilities with Interworking bit set
12884 * in Assoc Req.
12885 *
12886 * In assoc req this EXT Cap will only be taken into account if
12887 * interworkingService bit is set to 1. Currently
12888 * driver is only interested in interworkingService capability
12889 * from supplicant. If in future any other EXT Cap info is
12890 * required from supplicat, it needs to be handled while
12891 * sending Assoc Req in LIM.
12892 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012893 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012894 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012895 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012896 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012897 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012898
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012899 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012900 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012901 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12902 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012903 VOS_ASSERT(0);
12904 return -ENOMEM;
12905 }
12906 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12907 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012908
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012909 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12910 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12911 break;
12912 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012913#ifdef FEATURE_WLAN_WAPI
12914 case WLAN_EID_WAPI:
12915 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012916 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012917 pAdapter->wapi_info.nWapiMode);
12918 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012919 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070012920 akmsuiteCount = WPA_GET_LE16(tmp);
12921 tmp = tmp + 1;
12922 akmlist = (int *)(tmp);
12923 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
12924 {
12925 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
12926 }
12927 else
12928 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012929 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070012930 VOS_ASSERT(0);
12931 return -EINVAL;
12932 }
12933
12934 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
12935 {
12936 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012937 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012938 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012939 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012940 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012941 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012942 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012943 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012944 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
12945 }
12946 break;
12947#endif
12948 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012949 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012950 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012951 /* when Unknown IE is received we should break and continue
12952 * to the next IE in the buffer instead we were returning
12953 * so changing this to break */
12954 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070012955 }
12956 genie += eLen;
12957 remLen -= eLen;
12958 }
12959 EXIT();
12960 return 0;
12961}
12962
12963/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012964 * FUNCTION: hdd_isWPAIEPresent
12965 * Parse the received IE to find the WPA IE
12966 *
12967 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012968static bool hdd_isWPAIEPresent(
12969#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
12970 const u8 *ie,
12971#else
12972 u8 *ie,
12973#endif
12974 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012975{
12976 v_U8_t eLen = 0;
12977 v_U16_t remLen = ie_len;
12978 v_U8_t elementId = 0;
12979
12980 while (remLen >= 2)
12981 {
12982 elementId = *ie++;
12983 eLen = *ie++;
12984 remLen -= 2;
12985 if (eLen > remLen)
12986 {
12987 hddLog(VOS_TRACE_LEVEL_ERROR,
12988 "%s: IE length is wrong %d", __func__, eLen);
12989 return FALSE;
12990 }
12991 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
12992 {
12993 /* OUI - 0x00 0X50 0XF2
12994 WPA Information Element - 0x01
12995 WPA version - 0x01*/
12996 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
12997 return TRUE;
12998 }
12999 ie += eLen;
13000 remLen -= eLen;
13001 }
13002 return FALSE;
13003}
13004
13005/*
Jeff Johnson295189b2012-06-20 16:38:30 -070013006 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013007 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070013008 * parameters during connect operation.
13009 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013010int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013011 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013012 )
Jeff Johnson295189b2012-06-20 16:38:30 -070013013{
13014 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013015 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013016 ENTER();
13017
13018 /*set wpa version*/
13019 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
13020
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013021 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070013022 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053013023 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070013024 {
13025 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
13026 }
13027 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
13028 {
13029 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
13030 }
13031 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013032
13033 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013034 pWextState->wpaVersion);
13035
13036 /*set authentication type*/
13037 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
13038
13039 if (0 > status)
13040 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013041 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013042 "%s: failed to set authentication type ", __func__);
13043 return status;
13044 }
13045
13046 /*set key mgmt type*/
13047 if (req->crypto.n_akm_suites)
13048 {
13049 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
13050 if (0 > status)
13051 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013052 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070013053 __func__);
13054 return status;
13055 }
13056 }
13057
13058 /*set pairwise cipher type*/
13059 if (req->crypto.n_ciphers_pairwise)
13060 {
13061 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
13062 req->crypto.ciphers_pairwise[0], true);
13063 if (0 > status)
13064 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013065 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013066 "%s: failed to set unicast cipher type", __func__);
13067 return status;
13068 }
13069 }
13070 else
13071 {
13072 /*Reset previous cipher suite to none*/
13073 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
13074 if (0 > status)
13075 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013076 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013077 "%s: failed to set unicast cipher type", __func__);
13078 return status;
13079 }
13080 }
13081
13082 /*set group cipher type*/
13083 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
13084 false);
13085
13086 if (0 > status)
13087 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013088 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070013089 __func__);
13090 return status;
13091 }
13092
Chet Lanctot186b5732013-03-18 10:26:30 -070013093#ifdef WLAN_FEATURE_11W
13094 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
13095#endif
13096
Jeff Johnson295189b2012-06-20 16:38:30 -070013097 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
13098 if (req->ie_len)
13099 {
13100 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
13101 if ( 0 > status)
13102 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013103 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070013104 __func__);
13105 return status;
13106 }
13107 }
13108
13109 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013110 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070013111 {
13112 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
13113 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
13114 )
13115 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013116 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070013117 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
13118 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013119 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070013120 __func__);
13121 return -EOPNOTSUPP;
13122 }
13123 else
13124 {
13125 u8 key_len = req->key_len;
13126 u8 key_idx = req->key_idx;
13127
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013128 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070013129 && (CSR_MAX_NUM_KEY > key_idx)
13130 )
13131 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013132 hddLog(VOS_TRACE_LEVEL_INFO,
13133 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013134 __func__, key_idx, key_len);
13135 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013136 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070013137 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013138 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070013139 (u8)key_len;
13140 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
13141 }
13142 }
13143 }
13144 }
13145
13146 return status;
13147}
13148
13149/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053013150 * FUNCTION: wlan_hdd_try_disconnect
13151 * This function is used to disconnect from previous
13152 * connection
13153 */
13154static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
13155{
13156 long ret = 0;
13157 hdd_station_ctx_t *pHddStaCtx;
13158 eMib_dot11DesiredBssType connectedBssType;
13159
13160 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13161
13162 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
13163
13164 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
13165 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
13166 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
13167 {
13168 /* Issue disconnect to CSR */
13169 INIT_COMPLETION(pAdapter->disconnect_comp_var);
13170 if( eHAL_STATUS_SUCCESS ==
13171 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
13172 pAdapter->sessionId,
13173 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
13174 {
13175 ret = wait_for_completion_interruptible_timeout(
13176 &pAdapter->disconnect_comp_var,
13177 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
13178 if (0 >= ret)
13179 {
13180 hddLog(LOGE, FL("Failed to receive disconnect event"));
13181 return -EALREADY;
13182 }
13183 }
13184 }
13185 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
13186 {
13187 ret = wait_for_completion_interruptible_timeout(
13188 &pAdapter->disconnect_comp_var,
13189 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
13190 if (0 >= ret)
13191 {
13192 hddLog(LOGE, FL("Failed to receive disconnect event"));
13193 return -EALREADY;
13194 }
13195 }
13196
13197 return 0;
13198}
13199
13200/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053013201 * FUNCTION: __wlan_hdd_cfg80211_connect
13202 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070013203 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013204static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013205 struct net_device *ndev,
13206 struct cfg80211_connect_params *req
13207 )
13208{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013209 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013210 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013211 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053013212 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013213
13214 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013215
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013216 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13217 TRACE_CODE_HDD_CFG80211_CONNECT,
13218 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013219 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013220 "%s: device_mode = %s (%d)", __func__,
13221 hdd_device_modetoString(pAdapter->device_mode),
13222 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013223
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013224 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080013225 if (!pHddCtx)
13226 {
13227 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13228 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053013229 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080013230 }
13231
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013232 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013233 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013234 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013235 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013236 }
13237
Agarwal Ashish51325b52014-06-16 16:50:49 +053013238 if (vos_max_concurrent_connections_reached()) {
13239 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
13240 return -ECONNREFUSED;
13241 }
13242
Jeff Johnson295189b2012-06-20 16:38:30 -070013243#ifdef WLAN_BTAMP_FEATURE
13244 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013245 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070013246 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013247 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013248 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013249 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070013250 }
13251#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053013252
13253 //If Device Mode is Station Concurrent Sessions Exit BMps
13254 //P2P Mode will be taken care in Open/close adapter
13255 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053013256 (vos_concurrent_open_sessions_running())) {
13257 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
13258 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053013259 }
13260
13261 /*Try disconnecting if already in connected state*/
13262 status = wlan_hdd_try_disconnect(pAdapter);
13263 if ( 0 > status)
13264 {
13265 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
13266 " connection"));
13267 return -EALREADY;
13268 }
13269
Jeff Johnson295189b2012-06-20 16:38:30 -070013270 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013271 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070013272
13273 if ( 0 > status)
13274 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013275 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070013276 __func__);
13277 return status;
13278 }
Mohit Khanna765234a2012-09-11 15:08:35 -070013279 if ( req->channel )
13280 {
13281 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
13282 req->ssid_len, req->bssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013283 req->bssid_hint,
Mohit Khanna765234a2012-09-11 15:08:35 -070013284 req->channel->hw_value);
13285 }
13286 else
13287 {
13288 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013289 req->ssid_len, req->bssid,
13290 req->bssid_hint, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070013291 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013292
Sushant Kaushikd7083982015-03-18 14:33:24 +053013293 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013294 {
13295 //ReEnable BMPS if disabled
13296 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
13297 (NULL != pHddCtx))
13298 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053013299 if (pHddCtx->hdd_wlan_suspended)
13300 {
13301 hdd_set_pwrparams(pHddCtx);
13302 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013303 //ReEnable Bmps and Imps back
13304 hdd_enable_bmps_imps(pHddCtx);
13305 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053013306 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070013307 return status;
13308 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013309 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013310 EXIT();
13311 return status;
13312}
13313
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013314static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
13315 struct net_device *ndev,
13316 struct cfg80211_connect_params *req)
13317{
13318 int ret;
13319 vos_ssr_protect(__func__);
13320 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
13321 vos_ssr_unprotect(__func__);
13322
13323 return ret;
13324}
Jeff Johnson295189b2012-06-20 16:38:30 -070013325
13326/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013327 * FUNCTION: wlan_hdd_disconnect
13328 * This function is used to issue a disconnect request to SME
13329 */
13330int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
13331{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013332 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013333 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013334 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013335 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013336
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013337 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013338
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013339 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013340 if (0 != status)
13341 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013342 return status;
13343 }
13344
Sushant Kaushikb4834d22015-07-15 15:29:05 +053013345 if (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)
13346 {
13347 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
13348 pAdapter->sessionId);
13349 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013350 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013351
Agarwal Ashish47d18112014-08-04 19:55:07 +053013352 /* Need to apply spin lock before decreasing active sessions
13353 * as there can be chance for double decrement if context switch
13354 * Calls hdd_DisConnectHandler.
13355 */
13356
13357 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013358 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
13359 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013360 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
13361 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053013362 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
13363 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013364
Abhishek Singhf4669da2014-05-26 15:07:49 +053013365 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053013366 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
13367
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013368 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013369
Mihir Shete182a0b22014-08-18 16:08:48 +053013370 /*
13371 * stop tx queues before deleting STA/BSS context from the firmware.
13372 * tx has to be disabled because the firmware can get busy dropping
13373 * the tx frames after BSS/STA has been deleted and will not send
13374 * back a response resulting in WDI timeout
13375 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053013376 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053013377 netif_tx_disable(pAdapter->dev);
13378 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013379
Mihir Shete182a0b22014-08-18 16:08:48 +053013380 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013381 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
13382 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013383 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
13384 {
13385 hddLog(VOS_TRACE_LEVEL_INFO,
13386 FL("status = %d, already disconnected"),
13387 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013388
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013389 }
13390 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013391 {
13392 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013393 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013394 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013395 result = -EINVAL;
13396 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013397 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013398 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013399 &pAdapter->disconnect_comp_var,
13400 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013401 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013402 {
13403 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013404 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013405 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013406 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013407 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013408 {
13409 hddLog(VOS_TRACE_LEVEL_ERROR,
13410 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013411 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013412 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013413disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013414 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13415 FL("Set HDD connState to eConnectionState_NotConnected"));
13416 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
13417
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013418 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013419 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013420}
13421
13422
13423/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013424 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070013425 * This function is used to issue a disconnect request to SME
13426 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013427static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013428 struct net_device *dev,
13429 u16 reason
13430 )
13431{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013432 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013433 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013434 tCsrRoamProfile *pRoamProfile;
13435 hdd_station_ctx_t *pHddStaCtx;
13436 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013437#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013438 tANI_U8 staIdx;
13439#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013440
Jeff Johnson295189b2012-06-20 16:38:30 -070013441 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013442
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013443 if (!pAdapter) {
13444 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
13445 return -EINVAL;
13446 }
13447
13448 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13449 if (!pHddStaCtx) {
13450 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
13451 return -EINVAL;
13452 }
13453
13454 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13455 status = wlan_hdd_validate_context(pHddCtx);
13456 if (0 != status)
13457 {
13458 return status;
13459 }
13460
13461 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
13462
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013463 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13464 TRACE_CODE_HDD_CFG80211_DISCONNECT,
13465 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013466 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
13467 __func__, hdd_device_modetoString(pAdapter->device_mode),
13468 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013469
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013470 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
13471 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070013472
Jeff Johnson295189b2012-06-20 16:38:30 -070013473 if (NULL != pRoamProfile)
13474 {
13475 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053013476 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
13477 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070013478 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013479 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070013480 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013481 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070013482 switch(reason)
13483 {
13484 case WLAN_REASON_MIC_FAILURE:
13485 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
13486 break;
13487
13488 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
13489 case WLAN_REASON_DISASSOC_AP_BUSY:
13490 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
13491 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
13492 break;
13493
13494 case WLAN_REASON_PREV_AUTH_NOT_VALID:
13495 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053013496 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070013497 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
13498 break;
13499
Jeff Johnson295189b2012-06-20 16:38:30 -070013500 default:
13501 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
13502 break;
13503 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013504 pScanInfo = &pHddCtx->scan_info;
13505 if (pScanInfo->mScanPending)
13506 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053013507 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013508 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013509 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053013510 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013511 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053013512 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013513#ifdef FEATURE_WLAN_TDLS
13514 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013515 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013516 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013517 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
13518 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013519 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013520 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013521 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053013522 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013523 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013524 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013525 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053013526 status = sme_DeleteTdlsPeerSta(
13527 WLAN_HDD_GET_HAL_CTX(pAdapter),
13528 pAdapter->sessionId,
13529 mac);
13530 if (status != eHAL_STATUS_SUCCESS) {
13531 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
13532 return -EPERM;
13533 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013534 }
13535 }
13536#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013537 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013538 status = wlan_hdd_disconnect(pAdapter, reasonCode);
13539 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070013540 {
13541 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013542 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013543 __func__, (int)status );
13544 return -EINVAL;
13545 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013546 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053013547 else
13548 {
13549 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
13550 "called while in %d state", __func__,
13551 pHddStaCtx->conn_info.connState);
13552 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013553 }
13554 else
13555 {
13556 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
13557 }
13558
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013559 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013560 return status;
13561}
13562
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013563static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
13564 struct net_device *dev,
13565 u16 reason
13566 )
13567{
13568 int ret;
13569 vos_ssr_protect(__func__);
13570 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
13571 vos_ssr_unprotect(__func__);
13572
13573 return ret;
13574}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013575
Jeff Johnson295189b2012-06-20 16:38:30 -070013576/*
13577 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013578 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070013579 * settings in IBSS mode.
13580 */
13581static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013582 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013583 struct cfg80211_ibss_params *params
13584 )
13585{
13586 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013587 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013588 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13589 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013590
Jeff Johnson295189b2012-06-20 16:38:30 -070013591 ENTER();
13592
13593 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070013594 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070013595
13596 if (params->ie_len && ( NULL != params->ie) )
13597 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013598 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
13599 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070013600 {
13601 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
13602 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13603 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013604 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070013605 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013606 tDot11fIEWPA dot11WPAIE;
13607 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013608 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013609
Wilson Yang00256342013-10-10 23:13:38 -070013610 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013611 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
13612 params->ie_len, DOT11F_EID_WPA);
13613 if ( NULL != ie )
13614 {
13615 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
13616 // Unpack the WPA IE
13617 //Skip past the EID byte and length byte - and four byte WiFi OUI
13618 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
13619 &ie[2+4],
13620 ie[1] - 4,
13621 &dot11WPAIE);
13622 /*Extract the multicast cipher, the encType for unicast
13623 cipher for wpa-none is none*/
13624 encryptionType =
13625 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
13626 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013627 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013628
Jeff Johnson295189b2012-06-20 16:38:30 -070013629 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
13630
13631 if (0 > status)
13632 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013633 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070013634 __func__);
13635 return status;
13636 }
13637 }
13638
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013639 pWextState->roamProfile.AuthType.authType[0] =
13640 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070013641 eCSR_AUTH_TYPE_OPEN_SYSTEM;
13642
13643 if (params->privacy)
13644 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013645 /* Security enabled IBSS, At this time there is no information available
13646 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070013647 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013648 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070013649 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013650 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070013651 *enable privacy bit in beacons */
13652
13653 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13654 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013655 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
13656 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070013657 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13658 pWextState->roamProfile.EncryptionType.numEntries = 1;
13659 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070013660 return status;
13661}
13662
13663/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013664 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013665 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070013666 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013667static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013668 struct net_device *dev,
13669 struct cfg80211_ibss_params *params
13670 )
13671{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013672 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013673 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13674 tCsrRoamProfile *pRoamProfile;
13675 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013676 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13677 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013678 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070013679
13680 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013681
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013682 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13683 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
13684 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013685 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013686 "%s: device_mode = %s (%d)", __func__,
13687 hdd_device_modetoString(pAdapter->device_mode),
13688 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013689
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013690 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013691 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013692 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013693 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013694 }
13695
13696 if (NULL == pWextState)
13697 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013698 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070013699 __func__);
13700 return -EIO;
13701 }
13702
Agarwal Ashish51325b52014-06-16 16:50:49 +053013703 if (vos_max_concurrent_connections_reached()) {
13704 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
13705 return -ECONNREFUSED;
13706 }
13707
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053013708 /*Try disconnecting if already in connected state*/
13709 status = wlan_hdd_try_disconnect(pAdapter);
13710 if ( 0 > status)
13711 {
13712 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
13713 " IBSS connection"));
13714 return -EALREADY;
13715 }
13716
Jeff Johnson295189b2012-06-20 16:38:30 -070013717 pRoamProfile = &pWextState->roamProfile;
13718
13719 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
13720 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013721 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013722 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013723 return -EINVAL;
13724 }
13725
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013726 /* BSSID is provided by upper layers hence no need to AUTO generate */
13727 if (NULL != params->bssid) {
13728 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
13729 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
13730 hddLog (VOS_TRACE_LEVEL_ERROR,
13731 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
13732 return -EIO;
13733 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013734 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013735 }
krunal sonie9002db2013-11-25 14:24:17 -080013736 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
13737 {
13738 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
13739 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
13740 {
13741 hddLog (VOS_TRACE_LEVEL_ERROR,
13742 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
13743 return -EIO;
13744 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013745
13746 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080013747 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013748 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080013749 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013750
Jeff Johnson295189b2012-06-20 16:38:30 -070013751 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070013752 if (NULL !=
13753#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
13754 params->chandef.chan)
13755#else
13756 params->channel)
13757#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013758 {
13759 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013760 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
13761 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
13762 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13763 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013764
13765 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013766 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070013767 ieee80211_frequency_to_channel(
13768#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
13769 params->chandef.chan->center_freq);
13770#else
13771 params->channel->center_freq);
13772#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013773
13774 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
13775 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070013776 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013777 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
13778 __func__);
13779 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070013780 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013781
13782 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013783 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013784 if (channelNum == validChan[indx])
13785 {
13786 break;
13787 }
13788 }
13789 if (indx >= numChans)
13790 {
13791 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013792 __func__, channelNum);
13793 return -EINVAL;
13794 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013795 /* Set the Operational Channel */
13796 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
13797 channelNum);
13798 pRoamProfile->ChannelInfo.numOfChannels = 1;
13799 pHddStaCtx->conn_info.operationChannel = channelNum;
13800 pRoamProfile->ChannelInfo.ChannelList =
13801 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070013802 }
13803
13804 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013805 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070013806 if (status < 0)
13807 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013808 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070013809 __func__);
13810 return status;
13811 }
13812
13813 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013814 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Hanumantha Reddy Pothula64081b72015-09-11 15:47:32 +053013815 params->ssid_len, params->bssid, NULL,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013816 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013817
13818 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013819 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013820
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013821 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013822 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013823}
13824
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013825static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
13826 struct net_device *dev,
13827 struct cfg80211_ibss_params *params
13828 )
13829{
13830 int ret = 0;
13831
13832 vos_ssr_protect(__func__);
13833 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
13834 vos_ssr_unprotect(__func__);
13835
13836 return ret;
13837}
13838
Jeff Johnson295189b2012-06-20 16:38:30 -070013839/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013840 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013841 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070013842 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013843static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013844 struct net_device *dev
13845 )
13846{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013847 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013848 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13849 tCsrRoamProfile *pRoamProfile;
13850 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013851 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013852
13853 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013854
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013855 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13856 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
13857 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013858 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013859 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013860 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013861 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013862 }
13863
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013864 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
13865 hdd_device_modetoString(pAdapter->device_mode),
13866 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013867 if (NULL == pWextState)
13868 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013869 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070013870 __func__);
13871 return -EIO;
13872 }
13873
13874 pRoamProfile = &pWextState->roamProfile;
13875
13876 /* Issue disconnect only if interface type is set to IBSS */
13877 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
13878 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013879 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070013880 __func__);
13881 return -EINVAL;
13882 }
13883
13884 /* Issue Disconnect request */
13885 INIT_COMPLETION(pAdapter->disconnect_comp_var);
13886 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
13887 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
13888
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013889 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013890 return 0;
13891}
13892
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013893static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
13894 struct net_device *dev
13895 )
13896{
13897 int ret = 0;
13898
13899 vos_ssr_protect(__func__);
13900 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
13901 vos_ssr_unprotect(__func__);
13902
13903 return ret;
13904}
13905
Jeff Johnson295189b2012-06-20 16:38:30 -070013906/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013907 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070013908 * This function is used to set the phy parameters
13909 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
13910 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013911static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013912 u32 changed)
13913{
13914 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13915 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013916 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013917
13918 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013919
13920 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013921 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
13922 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013923
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013924 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013925 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013926 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013927 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013928 }
13929
Jeff Johnson295189b2012-06-20 16:38:30 -070013930 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
13931 {
13932 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
13933 WNI_CFG_RTS_THRESHOLD_STAMAX :
13934 wiphy->rts_threshold;
13935
13936 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013937 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070013938 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013939 hddLog(VOS_TRACE_LEVEL_ERROR,
13940 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013941 __func__, rts_threshold);
13942 return -EINVAL;
13943 }
13944
13945 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
13946 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013947 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013948 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013949 hddLog(VOS_TRACE_LEVEL_ERROR,
13950 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013951 __func__, rts_threshold);
13952 return -EIO;
13953 }
13954
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013955 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013956 rts_threshold);
13957 }
13958
13959 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
13960 {
13961 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
13962 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
13963 wiphy->frag_threshold;
13964
13965 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013966 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013967 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013968 hddLog(VOS_TRACE_LEVEL_ERROR,
13969 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013970 frag_threshold);
13971 return -EINVAL;
13972 }
13973
13974 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
13975 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013976 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013977 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013978 hddLog(VOS_TRACE_LEVEL_ERROR,
13979 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013980 __func__, frag_threshold);
13981 return -EIO;
13982 }
13983
13984 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
13985 frag_threshold);
13986 }
13987
13988 if ((changed & WIPHY_PARAM_RETRY_SHORT)
13989 || (changed & WIPHY_PARAM_RETRY_LONG))
13990 {
13991 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
13992 wiphy->retry_short :
13993 wiphy->retry_long;
13994
13995 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
13996 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
13997 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013998 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013999 __func__, retry_value);
14000 return -EINVAL;
14001 }
14002
14003 if (changed & WIPHY_PARAM_RETRY_SHORT)
14004 {
14005 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
14006 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014007 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070014008 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014009 hddLog(VOS_TRACE_LEVEL_ERROR,
14010 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014011 __func__, retry_value);
14012 return -EIO;
14013 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014014 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014015 __func__, retry_value);
14016 }
14017 else if (changed & WIPHY_PARAM_RETRY_SHORT)
14018 {
14019 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
14020 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014021 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070014022 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014023 hddLog(VOS_TRACE_LEVEL_ERROR,
14024 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014025 __func__, retry_value);
14026 return -EIO;
14027 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014028 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070014029 __func__, retry_value);
14030 }
14031 }
14032
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014033 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014034 return 0;
14035}
14036
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053014037static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
14038 u32 changed)
14039{
14040 int ret;
14041
14042 vos_ssr_protect(__func__);
14043 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
14044 vos_ssr_unprotect(__func__);
14045
14046 return ret;
14047}
14048
Jeff Johnson295189b2012-06-20 16:38:30 -070014049/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053014050 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070014051 * This function is used to set the txpower
14052 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053014053static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070014054#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
14055 struct wireless_dev *wdev,
14056#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014057#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014058 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070014059#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014060 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070014061#endif
14062 int dbm)
14063{
14064 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014065 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070014066 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
14067 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014068 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014069
14070 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014071
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014072 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14073 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
14074 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014075 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014076 if (0 != status)
14077 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014078 return status;
14079 }
14080
14081 hHal = pHddCtx->hHal;
14082
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014083 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
14084 dbm, ccmCfgSetCallback,
14085 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070014086 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014087 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014088 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
14089 return -EIO;
14090 }
14091
14092 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
14093 dbm);
14094
14095 switch(type)
14096 {
14097 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
14098 /* Fall through */
14099 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
14100 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
14101 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014102 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
14103 __func__);
14104 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070014105 }
14106 break;
14107 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014108 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070014109 __func__);
14110 return -EOPNOTSUPP;
14111 break;
14112 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014113 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
14114 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070014115 return -EIO;
14116 }
14117
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014118 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014119 return 0;
14120}
14121
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053014122static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
14123#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
14124 struct wireless_dev *wdev,
14125#endif
14126#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
14127 enum tx_power_setting type,
14128#else
14129 enum nl80211_tx_power_setting type,
14130#endif
14131 int dbm)
14132{
14133 int ret;
14134 vos_ssr_protect(__func__);
14135 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
14136#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
14137 wdev,
14138#endif
14139#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
14140 type,
14141#else
14142 type,
14143#endif
14144 dbm);
14145 vos_ssr_unprotect(__func__);
14146
14147 return ret;
14148}
14149
Jeff Johnson295189b2012-06-20 16:38:30 -070014150/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014151 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070014152 * This function is used to read the txpower
14153 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014154static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070014155#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
14156 struct wireless_dev *wdev,
14157#endif
14158 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070014159{
14160
14161 hdd_adapter_t *pAdapter;
14162 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014163 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014164
Jeff Johnsone7245742012-09-05 17:12:55 -070014165 ENTER();
14166
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014167 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014168 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014169 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014170 *dbm = 0;
14171 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014172 }
14173
Jeff Johnson295189b2012-06-20 16:38:30 -070014174 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
14175 if (NULL == pAdapter)
14176 {
14177 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
14178 return -ENOENT;
14179 }
14180
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014181 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14182 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
14183 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070014184 wlan_hdd_get_classAstats(pAdapter);
14185 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
14186
Jeff Johnsone7245742012-09-05 17:12:55 -070014187 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014188 return 0;
14189}
14190
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014191static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
14192#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
14193 struct wireless_dev *wdev,
14194#endif
14195 int *dbm)
14196{
14197 int ret;
14198
14199 vos_ssr_protect(__func__);
14200 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
14201#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
14202 wdev,
14203#endif
14204 dbm);
14205 vos_ssr_unprotect(__func__);
14206
14207 return ret;
14208}
14209
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014210static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014211#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14212 const u8* mac,
14213#else
14214 u8* mac,
14215#endif
14216 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070014217{
14218 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
14219 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
14220 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053014221 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070014222
14223 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
14224 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070014225
14226 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
14227 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
14228 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
14229 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
14230 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
14231 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
14232 tANI_U16 maxRate = 0;
14233 tANI_U16 myRate;
14234 tANI_U16 currentRate = 0;
14235 tANI_U8 maxSpeedMCS = 0;
14236 tANI_U8 maxMCSIdx = 0;
14237 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053014238 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014239 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014240 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014241
Leo Chang6f8870f2013-03-26 18:11:36 -070014242#ifdef WLAN_FEATURE_11AC
14243 tANI_U32 vht_mcs_map;
14244 eDataRate11ACMaxMcs vhtMaxMcs;
14245#endif /* WLAN_FEATURE_11AC */
14246
Jeff Johnsone7245742012-09-05 17:12:55 -070014247 ENTER();
14248
Jeff Johnson295189b2012-06-20 16:38:30 -070014249 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
14250 (0 == ssidlen))
14251 {
14252 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
14253 " Invalid ssidlen, %d", __func__, ssidlen);
14254 /*To keep GUI happy*/
14255 return 0;
14256 }
14257
Mukul Sharma811205f2014-07-09 21:07:30 +053014258 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
14259 {
14260 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14261 "%s: Roaming in progress, so unable to proceed this request", __func__);
14262 return 0;
14263 }
14264
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014265 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014266 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014267 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014268 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014269 }
14270
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053014271 wlan_hdd_get_station_stats(pAdapter);
14272 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070014273
Kiet Lam3b17fc82013-09-27 05:24:08 +053014274 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
14275 sinfo->filled |= STATION_INFO_SIGNAL;
14276
c_hpothu09f19542014-05-30 21:53:31 +053014277 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053014278 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
14279 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053014280 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053014281 {
14282 rate_flags = pAdapter->maxRateFlags;
14283 }
c_hpothu44ff4e02014-05-08 00:13:57 +053014284
Jeff Johnson295189b2012-06-20 16:38:30 -070014285 //convert to the UI units of 100kbps
14286 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
14287
14288#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070014289 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 -070014290 sinfo->signal,
14291 pCfg->reportMaxLinkSpeed,
14292 myRate,
14293 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070014294 (int) pCfg->linkSpeedRssiMid,
14295 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070014296 (int) rate_flags,
14297 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070014298#endif //LINKSPEED_DEBUG_ENABLED
14299
14300 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
14301 {
14302 // we do not want to necessarily report the current speed
14303 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
14304 {
14305 // report the max possible speed
14306 rssidx = 0;
14307 }
14308 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
14309 {
14310 // report the max possible speed with RSSI scaling
14311 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
14312 {
14313 // report the max possible speed
14314 rssidx = 0;
14315 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070014316 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070014317 {
14318 // report middle speed
14319 rssidx = 1;
14320 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070014321 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
14322 {
14323 // report middle speed
14324 rssidx = 2;
14325 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014326 else
14327 {
14328 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070014329 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070014330 }
14331 }
14332 else
14333 {
14334 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
14335 hddLog(VOS_TRACE_LEVEL_ERROR,
14336 "%s: Invalid value for reportMaxLinkSpeed: %u",
14337 __func__, pCfg->reportMaxLinkSpeed);
14338 rssidx = 0;
14339 }
14340
14341 maxRate = 0;
14342
14343 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053014344 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
14345 OperationalRates, &ORLeng))
14346 {
14347 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
14348 /*To keep GUI happy*/
14349 return 0;
14350 }
14351
Jeff Johnson295189b2012-06-20 16:38:30 -070014352 for (i = 0; i < ORLeng; i++)
14353 {
Jeff Johnsone7245742012-09-05 17:12:55 -070014354 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070014355 {
14356 /* Validate Rate Set */
14357 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
14358 {
14359 currentRate = supported_data_rate[j].supported_rate[rssidx];
14360 break;
14361 }
14362 }
14363 /* Update MAX rate */
14364 maxRate = (currentRate > maxRate)?currentRate:maxRate;
14365 }
14366
14367 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053014368 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
14369 ExtendedRates, &ERLeng))
14370 {
14371 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
14372 /*To keep GUI happy*/
14373 return 0;
14374 }
14375
Jeff Johnson295189b2012-06-20 16:38:30 -070014376 for (i = 0; i < ERLeng; i++)
14377 {
Jeff Johnsone7245742012-09-05 17:12:55 -070014378 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070014379 {
14380 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
14381 {
14382 currentRate = supported_data_rate[j].supported_rate[rssidx];
14383 break;
14384 }
14385 }
14386 /* Update MAX rate */
14387 maxRate = (currentRate > maxRate)?currentRate:maxRate;
14388 }
c_hpothu79aab322014-07-14 21:11:01 +053014389
Kiet Lamb69f8dc2013-11-15 15:34:27 +053014390 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053014391 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053014392 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053014393 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070014394 {
c_hpothu79aab322014-07-14 21:11:01 +053014395 if (rate_flags & eHAL_TX_RATE_VHT80)
14396 mode = 2;
14397 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
14398 mode = 1;
14399 else
14400 mode = 0;
14401
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053014402 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
14403 MCSRates, &MCSLeng))
14404 {
14405 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
14406 /*To keep GUI happy*/
14407 return 0;
14408 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014409 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070014410#ifdef WLAN_FEATURE_11AC
14411 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014412 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070014413 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014414 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014415 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070014416 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070014417 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014418 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070014419 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014420 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070014421 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014422 maxMCSIdx = 7;
14423 }
14424 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
14425 {
14426 maxMCSIdx = 8;
14427 }
14428 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
14429 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014430 //VHT20 is supporting 0~8
14431 if (rate_flags & eHAL_TX_RATE_VHT20)
14432 maxMCSIdx = 8;
14433 else
14434 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070014435 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014436
c_hpothu79aab322014-07-14 21:11:01 +053014437 if (0 != rssidx)/*check for scaled */
14438 {
14439 //get middle rate MCS index if rssi=1/2
14440 for (i=0; i <= maxMCSIdx; i++)
14441 {
14442 if (sinfo->signal <= rssiMcsTbl[mode][i])
14443 {
14444 maxMCSIdx = i;
14445 break;
14446 }
14447 }
14448 }
14449
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014450 if (rate_flags & eHAL_TX_RATE_VHT80)
14451 {
14452 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
14453 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
14454 }
14455 else if (rate_flags & eHAL_TX_RATE_VHT40)
14456 {
14457 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
14458 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
14459 }
14460 else if (rate_flags & eHAL_TX_RATE_VHT20)
14461 {
14462 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
14463 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
14464 }
14465
Leo Chang6f8870f2013-03-26 18:11:36 -070014466 maxSpeedMCS = 1;
14467 if (currentRate > maxRate)
14468 {
14469 maxRate = currentRate;
14470 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014471
Leo Chang6f8870f2013-03-26 18:11:36 -070014472 }
14473 else
14474#endif /* WLAN_FEATURE_11AC */
14475 {
14476 if (rate_flags & eHAL_TX_RATE_HT40)
14477 {
14478 rateFlag |= 1;
14479 }
14480 if (rate_flags & eHAL_TX_RATE_SGI)
14481 {
14482 rateFlag |= 2;
14483 }
14484
Girish Gowli01abcee2014-07-31 20:18:55 +053014485 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053014486 if (rssidx == 1 || rssidx == 2)
14487 {
14488 //get middle rate MCS index if rssi=1/2
14489 for (i=0; i <= 7; i++)
14490 {
14491 if (sinfo->signal <= rssiMcsTbl[mode][i])
14492 {
14493 temp = i+1;
14494 break;
14495 }
14496 }
14497 }
c_hpothu79aab322014-07-14 21:11:01 +053014498
14499 for (i = 0; i < MCSLeng; i++)
14500 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014501 for (j = 0; j < temp; j++)
14502 {
14503 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
14504 {
14505 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053014506 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070014507 break;
14508 }
14509 }
14510 if ((j < temp) && (currentRate > maxRate))
14511 {
14512 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070014513 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014514 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053014515 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070014516 }
14517 }
14518
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014519 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
14520 {
14521 maxRate = myRate;
14522 maxSpeedMCS = 1;
14523 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
14524 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014525 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053014526 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070014527 {
14528 maxRate = myRate;
14529 if (rate_flags & eHAL_TX_RATE_LEGACY)
14530 {
14531 maxSpeedMCS = 0;
14532 }
14533 else
14534 {
14535 maxSpeedMCS = 1;
14536 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
14537 }
14538 }
14539
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014540 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070014541 {
14542 sinfo->txrate.legacy = maxRate;
14543#ifdef LINKSPEED_DEBUG_ENABLED
14544 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
14545#endif //LINKSPEED_DEBUG_ENABLED
14546 }
14547 else
14548 {
14549 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070014550#ifdef WLAN_FEATURE_11AC
14551 sinfo->txrate.nss = 1;
14552 if (rate_flags & eHAL_TX_RATE_VHT80)
14553 {
14554 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014555 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070014556 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014557 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070014558 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014559 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14560 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14561 }
14562 else if (rate_flags & eHAL_TX_RATE_VHT20)
14563 {
14564 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14565 }
14566#endif /* WLAN_FEATURE_11AC */
14567 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
14568 {
14569 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
14570 if (rate_flags & eHAL_TX_RATE_HT40)
14571 {
14572 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14573 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014574 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014575 if (rate_flags & eHAL_TX_RATE_SGI)
14576 {
14577 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
14578 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014579
Jeff Johnson295189b2012-06-20 16:38:30 -070014580#ifdef LINKSPEED_DEBUG_ENABLED
14581 pr_info("Reporting MCS rate %d flags %x\n",
14582 sinfo->txrate.mcs,
14583 sinfo->txrate.flags );
14584#endif //LINKSPEED_DEBUG_ENABLED
14585 }
14586 }
14587 else
14588 {
14589 // report current rate instead of max rate
14590
14591 if (rate_flags & eHAL_TX_RATE_LEGACY)
14592 {
14593 //provide to the UI in units of 100kbps
14594 sinfo->txrate.legacy = myRate;
14595#ifdef LINKSPEED_DEBUG_ENABLED
14596 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
14597#endif //LINKSPEED_DEBUG_ENABLED
14598 }
14599 else
14600 {
14601 //must be MCS
14602 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070014603#ifdef WLAN_FEATURE_11AC
14604 sinfo->txrate.nss = 1;
14605 if (rate_flags & eHAL_TX_RATE_VHT80)
14606 {
14607 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14608 }
14609 else
14610#endif /* WLAN_FEATURE_11AC */
14611 {
14612 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
14613 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014614 if (rate_flags & eHAL_TX_RATE_SGI)
14615 {
14616 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
14617 }
14618 if (rate_flags & eHAL_TX_RATE_HT40)
14619 {
14620 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14621 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014622#ifdef WLAN_FEATURE_11AC
14623 else if (rate_flags & eHAL_TX_RATE_VHT80)
14624 {
14625 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
14626 }
14627#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070014628#ifdef LINKSPEED_DEBUG_ENABLED
14629 pr_info("Reporting actual MCS rate %d flags %x\n",
14630 sinfo->txrate.mcs,
14631 sinfo->txrate.flags );
14632#endif //LINKSPEED_DEBUG_ENABLED
14633 }
14634 }
14635 sinfo->filled |= STATION_INFO_TX_BITRATE;
14636
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070014637 sinfo->tx_packets =
14638 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
14639 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
14640 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
14641 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
14642
14643 sinfo->tx_retries =
14644 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
14645 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
14646 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
14647 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
14648
14649 sinfo->tx_failed =
14650 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
14651 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
14652 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
14653 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
14654
14655 sinfo->filled |=
14656 STATION_INFO_TX_PACKETS |
14657 STATION_INFO_TX_RETRIES |
14658 STATION_INFO_TX_FAILED;
14659
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014660 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14661 TRACE_CODE_HDD_CFG80211_GET_STA,
14662 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070014663 EXIT();
14664 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014665}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014666#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14667static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
14668 const u8* mac, struct station_info *sinfo)
14669#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014670static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
14671 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014672#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014673{
14674 int ret;
14675
14676 vos_ssr_protect(__func__);
14677 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
14678 vos_ssr_unprotect(__func__);
14679
14680 return ret;
14681}
14682
14683static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070014684 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070014685{
14686 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014687 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014688 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014689 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014690
Jeff Johnsone7245742012-09-05 17:12:55 -070014691 ENTER();
14692
Jeff Johnson295189b2012-06-20 16:38:30 -070014693 if (NULL == pAdapter)
14694 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014695 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014696 return -ENODEV;
14697 }
14698
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014699 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14700 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
14701 pAdapter->sessionId, timeout));
14702
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014703 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014704 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014705 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014706 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014707 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014708 }
14709
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014710 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
14711 (TRUE == pHddCtx->hdd_wlan_suspended) &&
14712 (pHddCtx->cfg_ini->fhostArpOffload) &&
14713 (eConnectionState_Associated ==
14714 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
14715 {
Amar Singhald53568e2013-09-26 11:03:45 -070014716
14717 hddLog(VOS_TRACE_LEVEL_INFO,
14718 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053014719 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014720 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14721 {
14722 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014723 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014724 __func__, vos_status);
14725 }
14726 }
14727
Jeff Johnson295189b2012-06-20 16:38:30 -070014728 /**The get power cmd from the supplicant gets updated by the nl only
14729 *on successful execution of the function call
14730 *we are oppositely mapped w.r.t mode in the driver
14731 **/
14732 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
14733
14734 if (VOS_STATUS_E_FAILURE == vos_status)
14735 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014736 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14737 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014738 return -EINVAL;
14739 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014740 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014741 return 0;
14742}
14743
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014744static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
14745 struct net_device *dev, bool mode, int timeout)
14746{
14747 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014748
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014749 vos_ssr_protect(__func__);
14750 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
14751 vos_ssr_unprotect(__func__);
14752
14753 return ret;
14754}
Sushant Kaushik084f6592015-09-10 13:11:56 +053014755
Jeff Johnson295189b2012-06-20 16:38:30 -070014756#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014757static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
14758 struct net_device *netdev,
14759 u8 key_index)
14760{
14761 ENTER();
14762 return 0;
14763}
14764
Jeff Johnson295189b2012-06-20 16:38:30 -070014765static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014766 struct net_device *netdev,
14767 u8 key_index)
14768{
14769 int ret;
14770 vos_ssr_protect(__func__);
14771 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
14772 vos_ssr_unprotect(__func__);
14773 return ret;
14774}
14775#endif //LINUX_VERSION_CODE
14776
14777#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
14778static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
14779 struct net_device *dev,
14780 struct ieee80211_txq_params *params)
14781{
14782 ENTER();
14783 return 0;
14784}
14785#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14786static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
14787 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070014788{
Jeff Johnsone7245742012-09-05 17:12:55 -070014789 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070014790 return 0;
14791}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014792#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070014793
14794#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
14795static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014796 struct net_device *dev,
14797 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070014798{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014799 int ret;
14800
14801 vos_ssr_protect(__func__);
14802 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
14803 vos_ssr_unprotect(__func__);
14804 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014805}
14806#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14807static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
14808 struct ieee80211_txq_params *params)
14809{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014810 int ret;
14811
14812 vos_ssr_protect(__func__);
14813 ret = __wlan_hdd_set_txq_params(wiphy, params);
14814 vos_ssr_unprotect(__func__);
14815 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014816}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014817#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014818
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014819static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014820 struct net_device *dev,
14821 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070014822{
14823 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014824 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014825 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014826 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014827 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014828 v_CONTEXT_t pVosContext = NULL;
14829 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014830
Jeff Johnsone7245742012-09-05 17:12:55 -070014831 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014832
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014833 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070014834 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014835 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014836 return -EINVAL;
14837 }
14838
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014839 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14840 TRACE_CODE_HDD_CFG80211_DEL_STA,
14841 pAdapter->sessionId, pAdapter->device_mode));
14842
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014843 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14844 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014845 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014846 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014847 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014848 }
14849
Jeff Johnson295189b2012-06-20 16:38:30 -070014850 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014851 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014852 )
14853 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014854 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14855 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14856 if(pSapCtx == NULL){
14857 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14858 FL("psapCtx is NULL"));
14859 return -ENOENT;
14860 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014861 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070014862 {
14863 v_U16_t i;
14864 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
14865 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014866 if ((pSapCtx->aStaInfo[i].isUsed) &&
14867 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070014868 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014869 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014870 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014871 ETHER_ADDR_LEN);
14872
Jeff Johnson295189b2012-06-20 16:38:30 -070014873 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014874 "%s: Delete STA with MAC::"
14875 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014876 __func__,
14877 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
14878 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070014879 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014880 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014881 }
14882 }
14883 }
14884 else
14885 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014886
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014887 vos_status = hdd_softap_GetStaId(pAdapter,
14888 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014889 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14890 {
14891 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014892 "%s: Skip this DEL STA as this is not used::"
14893 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014894 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014895 return -ENOENT;
14896 }
14897
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014898 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014899 {
14900 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014901 "%s: Skip this DEL STA as deauth is in progress::"
14902 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014903 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014904 return -ENOENT;
14905 }
14906
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014907 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014908
Jeff Johnson295189b2012-06-20 16:38:30 -070014909 hddLog(VOS_TRACE_LEVEL_INFO,
14910 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080014911 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014912 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014913 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014914
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014915 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014916 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14917 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014918 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014919 hddLog(VOS_TRACE_LEVEL_INFO,
14920 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080014921 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014922 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014923 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014924 return -ENOENT;
14925 }
14926
Jeff Johnson295189b2012-06-20 16:38:30 -070014927 }
14928 }
14929
14930 EXIT();
14931
14932 return 0;
14933}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014934
14935#ifdef CFG80211_DEL_STA_V2
14936static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14937 struct net_device *dev,
14938 struct station_del_parameters *param)
14939#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014940#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14941static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14942 struct net_device *dev, const u8 *mac)
14943#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014944static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14945 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014946#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014947#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014948{
14949 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014950 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070014951
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014952 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014953
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014954#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014955 if (NULL == param) {
14956 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014957 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014958 return -EINVAL;
14959 }
14960
14961 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
14962 param->subtype, &delStaParams);
14963
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014964#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053014965 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014966 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014967#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014968 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
14969
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014970 vos_ssr_unprotect(__func__);
14971
14972 return ret;
14973}
14974
14975static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014976 struct net_device *dev,
14977#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14978 const u8 *mac,
14979#else
14980 u8 *mac,
14981#endif
14982 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014983{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014984 hdd_adapter_t *pAdapter;
14985 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014986 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014987#ifdef FEATURE_WLAN_TDLS
14988 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014989
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014990 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014991
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014992 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14993 if (NULL == pAdapter)
14994 {
14995 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14996 "%s: Adapter is NULL",__func__);
14997 return -EINVAL;
14998 }
14999 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15000 status = wlan_hdd_validate_context(pHddCtx);
15001 if (0 != status)
15002 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015003 return status;
15004 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015005
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015006 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15007 TRACE_CODE_HDD_CFG80211_ADD_STA,
15008 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015009 mask = params->sta_flags_mask;
15010
15011 set = params->sta_flags_set;
15012
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015013 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015014 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
15015 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015016
15017 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
15018 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080015019 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015020 }
15021 }
15022#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015023 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015024 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070015025}
15026
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015027#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15028static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
15029 struct net_device *dev, const u8 *mac,
15030 struct station_parameters *params)
15031#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015032static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
15033 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053015034#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015035{
15036 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015037
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015038 vos_ssr_protect(__func__);
15039 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
15040 vos_ssr_unprotect(__func__);
15041
15042 return ret;
15043}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015044#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070015045
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053015046static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070015047 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015048{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015049 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15050 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015051 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015052 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015053 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015054 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070015055
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015056 ENTER();
15057
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015058 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015059 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015060 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015061 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015062 return -EINVAL;
15063 }
15064
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015065 if (!pmksa) {
15066 hddLog(LOGE, FL("pmksa is NULL"));
15067 return -EINVAL;
15068 }
15069
15070 if (!pmksa->bssid || !pmksa->pmkid) {
15071 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
15072 pmksa->bssid, pmksa->pmkid);
15073 return -EINVAL;
15074 }
15075
15076 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
15077 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
15078
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015079 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15080 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015081 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015082 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015083 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015084 }
15085
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015086 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015087 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
15088
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015089 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
15090 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015091
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015092 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015093 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015094 &pmk_id, 1, FALSE);
15095
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015096 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15097 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
15098 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015099
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015100 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015101 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015102}
15103
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053015104static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
15105 struct cfg80211_pmksa *pmksa)
15106{
15107 int ret;
15108
15109 vos_ssr_protect(__func__);
15110 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
15111 vos_ssr_unprotect(__func__);
15112
15113 return ret;
15114}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015115
Wilson Yang6507c4e2013-10-01 20:11:19 -070015116
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053015117static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070015118 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015119{
Wilson Yang6507c4e2013-10-01 20:11:19 -070015120 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15121 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070015122 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080015123 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070015124
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015125 ENTER();
15126
Wilson Yang6507c4e2013-10-01 20:11:19 -070015127 /* Validate pAdapter */
15128 if (NULL == pAdapter)
15129 {
15130 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
15131 return -EINVAL;
15132 }
15133
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015134 if (!pmksa) {
15135 hddLog(LOGE, FL("pmksa is NULL"));
15136 return -EINVAL;
15137 }
15138
15139 if (!pmksa->bssid) {
15140 hddLog(LOGE, FL("pmksa->bssid is NULL"));
15141 return -EINVAL;
15142 }
15143
Kiet Lam98c46a12014-10-31 15:34:57 -070015144 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
15145 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
15146
Wilson Yang6507c4e2013-10-01 20:11:19 -070015147 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15148 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070015149 if (0 != status)
15150 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070015151 return status;
15152 }
15153
15154 /*Retrieve halHandle*/
15155 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
15156
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015157 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15158 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
15159 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015160 /* Delete the PMKID CSR cache */
15161 if (eHAL_STATUS_SUCCESS !=
15162 sme_RoamDelPMKIDfromCache(halHandle,
15163 pAdapter->sessionId, pmksa->bssid, FALSE)) {
15164 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
15165 MAC_ADDR_ARRAY(pmksa->bssid));
15166 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070015167 }
15168
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015169 EXIT();
15170 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015171}
15172
Wilson Yang6507c4e2013-10-01 20:11:19 -070015173
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053015174static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
15175 struct cfg80211_pmksa *pmksa)
15176{
15177 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070015178
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053015179 vos_ssr_protect(__func__);
15180 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
15181 vos_ssr_unprotect(__func__);
15182
15183 return ret;
15184
15185}
15186
15187static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015188{
Wilson Yang6507c4e2013-10-01 20:11:19 -070015189 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15190 tHalHandle halHandle;
15191 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080015192 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070015193
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015194 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070015195
15196 /* Validate pAdapter */
15197 if (NULL == pAdapter)
15198 {
15199 hddLog(VOS_TRACE_LEVEL_ERROR,
15200 "%s: Invalid Adapter" ,__func__);
15201 return -EINVAL;
15202 }
15203
15204 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15205 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070015206 if (0 != status)
15207 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070015208 return status;
15209 }
15210
15211 /*Retrieve halHandle*/
15212 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
15213
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053015214 /* Flush the PMKID cache in CSR */
15215 if (eHAL_STATUS_SUCCESS !=
15216 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
15217 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
15218 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070015219 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015220 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080015221 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015222}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053015223
15224static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
15225{
15226 int ret;
15227
15228 vos_ssr_protect(__func__);
15229 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
15230 vos_ssr_unprotect(__func__);
15231
15232 return ret;
15233}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015234#endif
15235
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015236#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015237static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
15238 struct net_device *dev,
15239 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015240{
15241 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15242 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015243 hdd_context_t *pHddCtx;
15244 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015245
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015246 ENTER();
15247
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015248 if (NULL == pAdapter)
15249 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015250 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015251 return -ENODEV;
15252 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015253 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15254 ret = wlan_hdd_validate_context(pHddCtx);
15255 if (0 != ret)
15256 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015257 return ret;
15258 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015259 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015260 if (NULL == pHddStaCtx)
15261 {
15262 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
15263 return -EINVAL;
15264 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015265
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015266 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15267 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
15268 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015269 // Added for debug on reception of Re-assoc Req.
15270 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
15271 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015272 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015273 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080015274 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015275 }
15276
15277#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080015278 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015279 ftie->ie_len);
15280#endif
15281
15282 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015283 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
15284 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015285 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015286
15287 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015288 return 0;
15289}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015290
15291static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
15292 struct net_device *dev,
15293 struct cfg80211_update_ft_ies_params *ftie)
15294{
15295 int ret;
15296
15297 vos_ssr_protect(__func__);
15298 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
15299 vos_ssr_unprotect(__func__);
15300
15301 return ret;
15302}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015303#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015304
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015305#ifdef FEATURE_WLAN_SCAN_PNO
15306
15307void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
15308 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
15309{
15310 int ret;
15311 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
15312 hdd_context_t *pHddCtx;
15313
Nirav Shah80830bf2013-12-31 16:35:12 +053015314 ENTER();
15315
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015316 if (NULL == pAdapter)
15317 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053015318 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015319 "%s: HDD adapter is Null", __func__);
15320 return ;
15321 }
15322
15323 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15324 if (NULL == pHddCtx)
15325 {
15326 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15327 "%s: HDD context is Null!!!", __func__);
15328 return ;
15329 }
15330
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015331 spin_lock(&pHddCtx->schedScan_lock);
15332 if (TRUE == pHddCtx->isWiphySuspended)
15333 {
15334 pHddCtx->isSchedScanUpdatePending = TRUE;
15335 spin_unlock(&pHddCtx->schedScan_lock);
15336 hddLog(VOS_TRACE_LEVEL_INFO,
15337 "%s: Update cfg80211 scan database after it resume", __func__);
15338 return ;
15339 }
15340 spin_unlock(&pHddCtx->schedScan_lock);
15341
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015342 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
15343
15344 if (0 > ret)
15345 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
15346
15347 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015348 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15349 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015350}
15351
15352/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015353 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015354 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015355 */
15356static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
15357{
15358 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15359 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015360 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015361 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15362 int status = 0;
15363 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
15364
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015365 /* The current firmware design does not allow PNO during any
15366 * active sessions. Hence, determine the active sessions
15367 * and return a failure.
15368 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015369 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
15370 {
15371 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015372 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015373
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015374 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
15375 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
15376 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
15377 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
15378 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053015379 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015380 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015381 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015382 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015383 }
15384 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15385 pAdapterNode = pNext;
15386 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015387 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015388}
15389
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015390void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
15391{
15392 hdd_adapter_t *pAdapter = callbackContext;
15393 hdd_context_t *pHddCtx;
15394
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015395 ENTER();
15396
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015397 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
15398 {
15399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15400 FL("Invalid adapter or adapter has invalid magic"));
15401 return;
15402 }
15403
15404 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15405 if (0 != wlan_hdd_validate_context(pHddCtx))
15406 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015407 return;
15408 }
15409
c_hpothub53c45d2014-08-18 16:53:14 +053015410 if (VOS_STATUS_SUCCESS != status)
15411 {
15412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015413 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053015414 pHddCtx->isPnoEnable = FALSE;
15415 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015416
15417 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
15418 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015419 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015420}
15421
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015422/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015423 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
15424 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015425 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015426static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015427 struct net_device *dev, struct cfg80211_sched_scan_request *request)
15428{
15429 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015430 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015431 hdd_context_t *pHddCtx;
15432 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015433 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053015434 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
15435 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015436 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
15437 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015438 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015439 hdd_config_t *pConfig = NULL;
15440 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015441
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015442 ENTER();
15443
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015444 if (NULL == pAdapter)
15445 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015447 "%s: HDD adapter is Null", __func__);
15448 return -ENODEV;
15449 }
15450
15451 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015452 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015453
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015454 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015455 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015456 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015457 }
15458
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015459 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015460 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15461 if (NULL == hHal)
15462 {
15463 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15464 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015465 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015466 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015467 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15468 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
15469 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053015470 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015471 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053015472 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015473 {
15474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15475 "%s: aborting the existing scan is unsuccessfull", __func__);
15476 return -EBUSY;
15477 }
15478
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015479 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015480 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015481 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015482 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015483 return -EBUSY;
15484 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015485
c_hpothu37f21312014-04-09 21:49:54 +053015486 if (TRUE == pHddCtx->isPnoEnable)
15487 {
15488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15489 FL("already PNO is enabled"));
15490 return -EBUSY;
15491 }
c_hpothu225aa7c2014-10-22 17:45:13 +053015492
15493 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
15494 {
15495 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15496 "%s: abort ROC failed ", __func__);
15497 return -EBUSY;
15498 }
15499
c_hpothu37f21312014-04-09 21:49:54 +053015500 pHddCtx->isPnoEnable = TRUE;
15501
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015502 pnoRequest.enable = 1; /*Enable PNO */
15503 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015504
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015505 if (( !pnoRequest.ucNetworksCount ) ||
15506 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015507 {
15508 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015509 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015510 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015511 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015512 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015513 goto error;
15514 }
15515
15516 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
15517 {
15518 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015519 "%s: Incorrect number of channels %d",
15520 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015521 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015522 goto error;
15523 }
15524
15525 /* Framework provides one set of channels(all)
15526 * common for all saved profile */
15527 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
15528 channels_allowed, &num_channels_allowed))
15529 {
15530 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15531 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015532 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015533 goto error;
15534 }
15535 /* Checking each channel against allowed channel list */
15536 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053015537 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015538 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015539 char chList [(request->n_channels*5)+1];
15540 int len;
15541 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015542 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015543 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015544 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015545 if (request->channels[i]->hw_value == channels_allowed[indx])
15546 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015547 if ((!pConfig->enableDFSPnoChnlScan) &&
15548 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
15549 {
15550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15551 "%s : Dropping DFS channel : %d",
15552 __func__,channels_allowed[indx]);
15553 num_ignore_dfs_ch++;
15554 break;
15555 }
15556
Nirav Shah80830bf2013-12-31 16:35:12 +053015557 valid_ch[num_ch++] = request->channels[i]->hw_value;
15558 len += snprintf(chList+len, 5, "%d ",
15559 request->channels[i]->hw_value);
15560 break ;
15561 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015562 }
15563 }
Nirav Shah80830bf2013-12-31 16:35:12 +053015564 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015565
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015566 /*If all channels are DFS and dropped, then ignore the PNO request*/
15567 if (num_ignore_dfs_ch == request->n_channels)
15568 {
15569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15570 "%s : All requested channels are DFS channels", __func__);
15571 ret = -EINVAL;
15572 goto error;
15573 }
15574 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015575
15576 pnoRequest.aNetworks =
15577 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15578 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015579 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015580 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15581 FL("failed to allocate memory aNetworks %u"),
15582 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15583 goto error;
15584 }
15585 vos_mem_zero(pnoRequest.aNetworks,
15586 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15587
15588 /* Filling per profile params */
15589 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
15590 {
15591 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015592 request->match_sets[i].ssid.ssid_len;
15593
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015594 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
15595 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015596 {
15597 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015598 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015599 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015600 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015601 goto error;
15602 }
15603
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015604 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015605 request->match_sets[i].ssid.ssid,
15606 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15608 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015609 i, pnoRequest.aNetworks[i].ssId.ssId);
15610 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
15611 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
15612 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015613
15614 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015615 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
15616 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015617
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015618 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015619 }
15620
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015621 for (i = 0; i < request->n_ssids; i++)
15622 {
15623 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015624 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015625 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015626 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015627 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015628 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015629 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015630 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015631 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015632 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015633 break;
15634 }
15635 j++;
15636 }
15637 }
15638 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15639 "Number of hidden networks being Configured = %d",
15640 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015641 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080015642 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015643
15644 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
15645 if (pnoRequest.p24GProbeTemplate == NULL)
15646 {
15647 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15648 FL("failed to allocate memory p24GProbeTemplate %u"),
15649 SIR_PNO_MAX_PB_REQ_SIZE);
15650 goto error;
15651 }
15652
15653 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
15654 if (pnoRequest.p5GProbeTemplate == NULL)
15655 {
15656 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15657 FL("failed to allocate memory p5GProbeTemplate %u"),
15658 SIR_PNO_MAX_PB_REQ_SIZE);
15659 goto error;
15660 }
15661
15662 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
15663 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
15664
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053015665 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
15666 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015667 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015668 pnoRequest.us24GProbeTemplateLen = request->ie_len;
15669 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
15670 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015671
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015672 pnoRequest.us5GProbeTemplateLen = request->ie_len;
15673 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
15674 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015675 }
15676
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015677 /* Driver gets only one time interval which is hardcoded in
15678 * supplicant for 10000ms. Taking power consumption into account 6 timers
15679 * will be used, Timervalue is increased exponentially i.e 10,20,40,
15680 * 80,160,320 secs. And number of scan cycle for each timer
15681 * is configurable through INI param gPNOScanTimerRepeatValue.
15682 * If it is set to 0 only one timer will be used and PNO scan cycle
15683 * will be repeated after each interval specified by supplicant
15684 * till PNO is disabled.
15685 */
15686 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015687 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015688 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015689 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015690 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
15691
15692 tempInterval = (request->interval)/1000;
15693 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15694 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
15695 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015696 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015697 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015698 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015699 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015700 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015701 tempInterval *= 2;
15702 }
15703 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015704 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015705
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015706 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015707
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015708 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015709 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
15710 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015711 pAdapter->pno_req_status = 0;
15712
Nirav Shah80830bf2013-12-31 16:35:12 +053015713 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15714 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015715 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
15716 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053015717
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015718 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015719 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015720 hdd_cfg80211_sched_scan_done_callback, pAdapter);
15721 if (eHAL_STATUS_SUCCESS != status)
15722 {
15723 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015724 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015725 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015726 goto error;
15727 }
15728
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015729 ret = wait_for_completion_timeout(
15730 &pAdapter->pno_comp_var,
15731 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
15732 if (0 >= ret)
15733 {
15734 // Did not receive the response for PNO enable in time.
15735 // Assuming the PNO enable was success.
15736 // Returning error from here, because we timeout, results
15737 // in side effect of Wifi (Wifi Setting) not to work.
15738 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15739 FL("Timed out waiting for PNO to be Enabled"));
15740 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015741 }
15742
15743 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053015744 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015745
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015746error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015747 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15748 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053015749 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015750 if (pnoRequest.aNetworks)
15751 vos_mem_free(pnoRequest.aNetworks);
15752 if (pnoRequest.p24GProbeTemplate)
15753 vos_mem_free(pnoRequest.p24GProbeTemplate);
15754 if (pnoRequest.p5GProbeTemplate)
15755 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015756
15757 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015758 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015759}
15760
15761/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015762 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
15763 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015764 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015765static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
15766 struct net_device *dev, struct cfg80211_sched_scan_request *request)
15767{
15768 int ret;
15769
15770 vos_ssr_protect(__func__);
15771 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
15772 vos_ssr_unprotect(__func__);
15773
15774 return ret;
15775}
15776
15777/*
15778 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
15779 * Function to disable PNO
15780 */
15781static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015782 struct net_device *dev)
15783{
15784 eHalStatus status = eHAL_STATUS_FAILURE;
15785 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15786 hdd_context_t *pHddCtx;
15787 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015788 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015789 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015790
15791 ENTER();
15792
15793 if (NULL == pAdapter)
15794 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015796 "%s: HDD adapter is Null", __func__);
15797 return -ENODEV;
15798 }
15799
15800 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015801
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015802 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015803 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015804 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015805 "%s: HDD context is Null", __func__);
15806 return -ENODEV;
15807 }
15808
15809 /* The return 0 is intentional when isLogpInProgress and
15810 * isLoadUnloadInProgress. We did observe a crash due to a return of
15811 * failure in sched_scan_stop , especially for a case where the unload
15812 * of the happens at the same time. The function __cfg80211_stop_sched_scan
15813 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
15814 * success. If it returns a failure , then its next invocation due to the
15815 * clean up of the second interface will have the dev pointer corresponding
15816 * to the first one leading to a crash.
15817 */
15818 if (pHddCtx->isLogpInProgress)
15819 {
15820 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15821 "%s: LOGP in Progress. Ignore!!!", __func__);
15822 return ret;
15823 }
15824
Mihir Shete18156292014-03-11 15:38:30 +053015825 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015826 {
15827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15828 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15829 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015830 }
15831
15832 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15833 if (NULL == hHal)
15834 {
15835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15836 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015837 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015838 }
15839
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015840 pnoRequest.enable = 0; /* Disable PNO */
15841 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015842
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015843 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15844 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
15845 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015846 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015847 pAdapter->sessionId,
15848 NULL, pAdapter);
15849 if (eHAL_STATUS_SUCCESS != status)
15850 {
15851 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15852 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015853 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015854 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015855 }
c_hpothu37f21312014-04-09 21:49:54 +053015856 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015857
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015858error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015859 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015860 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015861
15862 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015863 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015864}
15865
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015866/*
15867 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
15868 * NL interface to disable PNO
15869 */
15870static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
15871 struct net_device *dev)
15872{
15873 int ret;
15874
15875 vos_ssr_protect(__func__);
15876 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
15877 vos_ssr_unprotect(__func__);
15878
15879 return ret;
15880}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015881#endif /*FEATURE_WLAN_SCAN_PNO*/
15882
15883
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015884#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015885#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015886static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15887 struct net_device *dev,
15888 u8 *peer, u8 action_code,
15889 u8 dialog_token,
15890 u16 status_code, u32 peer_capability,
15891 const u8 *buf, size_t len)
15892#else /* TDLS_MGMT_VERSION2 */
15893#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
15894static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15895 struct net_device *dev,
15896 const u8 *peer, u8 action_code,
15897 u8 dialog_token, u16 status_code,
15898 u32 peer_capability, bool initiator,
15899 const u8 *buf, size_t len)
15900#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
15901static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15902 struct net_device *dev,
15903 const u8 *peer, u8 action_code,
15904 u8 dialog_token, u16 status_code,
15905 u32 peer_capability, const u8 *buf,
15906 size_t len)
15907#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
15908static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15909 struct net_device *dev,
15910 u8 *peer, u8 action_code,
15911 u8 dialog_token,
15912 u16 status_code, u32 peer_capability,
15913 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015914#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015915static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15916 struct net_device *dev,
15917 u8 *peer, u8 action_code,
15918 u8 dialog_token,
15919 u16 status_code, const u8 *buf,
15920 size_t len)
15921#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015922#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015923{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015924 hdd_adapter_t *pAdapter;
15925 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015926 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070015927 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080015928 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070015929 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015930 int ret;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015931#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015932 u32 peer_capability = 0;
15933#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015934 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015935 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015936
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015937 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15938 if (NULL == pAdapter)
15939 {
15940 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15941 "%s: Adapter is NULL",__func__);
15942 return -EINVAL;
15943 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015944 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15945 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
15946 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015947
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015948 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015949 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015950 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015952 "Invalid arguments");
15953 return -EINVAL;
15954 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015955
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015956 if (pHddCtx->isLogpInProgress)
15957 {
15958 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15959 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053015960 wlan_hdd_tdls_set_link_status(pAdapter,
15961 peer,
15962 eTDLS_LINK_IDLE,
15963 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015964 return -EBUSY;
15965 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015966
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015967 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
15968 {
15969 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15970 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15971 return -EAGAIN;
15972 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015973
Hoonki Lee27511902013-03-14 18:19:06 -070015974 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015975 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015976 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015977 "%s: TDLS mode is disabled OR not enabled in FW."
15978 MAC_ADDRESS_STR " action %d declined.",
15979 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015980 return -ENOTSUPP;
15981 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015982
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015983 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15984
15985 if( NULL == pHddStaCtx )
15986 {
15987 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15988 "%s: HDD station context NULL ",__func__);
15989 return -EINVAL;
15990 }
15991
15992 /* STA should be connected and authenticated
15993 * before sending any TDLS frames
15994 */
15995 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15996 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
15997 {
15998 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15999 "STA is not connected or unauthenticated. "
16000 "connState %u, uIsAuthenticated %u",
16001 pHddStaCtx->conn_info.connState,
16002 pHddStaCtx->conn_info.uIsAuthenticated);
16003 return -EAGAIN;
16004 }
16005
Hoonki Lee27511902013-03-14 18:19:06 -070016006 /* other than teardown frame, other mgmt frames are not sent if disabled */
16007 if (SIR_MAC_TDLS_TEARDOWN != action_code)
16008 {
16009 /* if tdls_mode is disabled to respond to peer's request */
16010 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
16011 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016012 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070016013 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070016014 " TDLS mode is disabled. action %d declined.",
16015 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070016016
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016017 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070016018 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053016019
16020 if (vos_max_concurrent_connections_reached())
16021 {
16022 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
16023 return -EINVAL;
16024 }
Hoonki Lee27511902013-03-14 18:19:06 -070016025 }
16026
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016027 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
16028 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053016029 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016030 {
16031 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016032 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070016033 " TDLS setup is ongoing. action %d declined.",
16034 __func__, MAC_ADDR_ARRAY(peer), action_code);
16035 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016036 }
16037 }
16038
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016039 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
16040 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080016041 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053016042 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
16043 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080016044 {
16045 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
16046 we return error code at 'add_station()'. Hence we have this
16047 check again in addtion to add_station().
16048 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016049 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080016050 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016051 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16052 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053016053 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
16054 __func__, MAC_ADDR_ARRAY(peer), action_code,
16055 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053016056 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080016057 }
16058 else
16059 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016060 /* maximum reached. tweak to send error code to peer and return
16061 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080016062 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016063 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16064 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053016065 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
16066 __func__, MAC_ADDR_ARRAY(peer), status_code,
16067 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070016068 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016069 /* fall through to send setup resp with failure status
16070 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080016071 }
16072 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016073 else
16074 {
16075 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053016076 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016077 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016078 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016079 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070016080 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
16081 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016082 return -EPERM;
16083 }
16084 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080016085 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016086
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016087 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053016088 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016089 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
16090 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016091
Hoonki Leea34dd892013-02-05 22:56:02 -080016092 /*Except teardown responder will not be used so just make 0*/
16093 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080016094 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080016095 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070016096
16097 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016098 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070016099
16100 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
16101 responder = pTdlsPeer->is_responder;
16102 else
Hoonki Leea34dd892013-02-05 22:56:02 -080016103 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070016104 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053016105 "%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 -070016106 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
16107 dialog_token, status_code, len);
16108 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080016109 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016110 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016111
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053016112 /* For explicit trigger of DIS_REQ come out of BMPS for
16113 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070016114 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053016115 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
16116 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070016117 {
16118 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
16119 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053016120 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053016121 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016122 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
16123 if (status != VOS_STATUS_SUCCESS) {
16124 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
16125 }
Hoonki Lee14621352013-04-16 17:51:19 -070016126 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016127 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016128 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016129 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
16130 }
16131 }
Hoonki Lee14621352013-04-16 17:51:19 -070016132 }
16133
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016134 /* make sure doesn't call send_mgmt() while it is pending */
16135 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
16136 {
16137 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080016138 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016139 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016140 ret = -EBUSY;
16141 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016142 }
16143
16144 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016145 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
16146
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016147 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
16148 pAdapter->sessionId, peer, action_code, dialog_token,
16149 status_code, peer_capability, (tANI_U8 *)buf, len,
16150 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016151
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016152 if (VOS_STATUS_SUCCESS != status)
16153 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016154 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16155 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016156 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016157 ret = -EINVAL;
16158 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016159 }
16160
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016161 if ((SIR_MAC_TDLS_DIS_REQ == action_code) ||
16162 (SIR_MAC_TDLS_DIS_RSP == action_code))
16163 {
16164 /* for DIS_REQ/DIS_RSP, supplicant don't consider the return status.
16165 * So we no need to wait for tdls_mgmt_comp for sending ack status.
16166 */
16167 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16168 "%s: tx done for frm %u", __func__, action_code);
16169 return 0;
16170 }
16171
16172 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16173 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
16174 WAIT_TIME_TDLS_MGMT);
16175
Hoonki Leed37cbb32013-04-20 00:31:14 -070016176 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
16177 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
16178
16179 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016180 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070016181 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070016182 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070016183 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016184 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080016185
16186 if (pHddCtx->isLogpInProgress)
16187 {
16188 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16189 "%s: LOGP in Progress. Ignore!!!", __func__);
16190 return -EAGAIN;
16191 }
Abhishek Singh837adf22015-10-01 17:37:37 +053016192 if (rc <= 0)
16193 vos_fatal_event_logs_req(WLAN_LOG_TYPE_FATAL,
16194 WLAN_LOG_INDICATOR_HOST_DRIVER,
16195 WLAN_LOG_REASON_HDD_TIME_OUT,
16196 TRUE, TRUE);
Yue Ma4f55ef32014-01-23 16:45:33 -080016197
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016198 ret = -EINVAL;
16199 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016200 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053016201 else
16202 {
16203 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16204 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
16205 __func__, rc, pAdapter->mgmtTxCompletionStatus);
16206 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016207
Gopichand Nakkala05922802013-03-14 12:23:19 -070016208 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070016209 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016210 ret = max_sta_failed;
16211 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070016212 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016213
Hoonki Leea34dd892013-02-05 22:56:02 -080016214 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
16215 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016216 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016217 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
16218 }
Hoonki Leea34dd892013-02-05 22:56:02 -080016219 }
16220 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
16221 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016222 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016223 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
16224 }
Hoonki Leea34dd892013-02-05 22:56:02 -080016225 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016226
16227 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053016228
16229tx_failed:
16230 /* add_station will be called before sending TDLS_SETUP_REQ and
16231 * TDLS_SETUP_RSP and as part of add_station driver will enable
16232 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
16233 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
16234 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
16235 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
16236 */
16237
16238 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
16239 (SIR_MAC_TDLS_SETUP_RSP == action_code))
16240 wlan_hdd_tdls_check_bmps(pAdapter);
16241 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016242}
16243
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016244#if TDLS_MGMT_VERSION2
16245static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
16246 u8 *peer, u8 action_code, u8 dialog_token,
16247 u16 status_code, u32 peer_capability,
16248 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016249#else /* TDLS_MGMT_VERSION2 */
16250#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
16251static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16252 struct net_device *dev,
16253 const u8 *peer, u8 action_code,
16254 u8 dialog_token, u16 status_code,
16255 u32 peer_capability, bool initiator,
16256 const u8 *buf, size_t len)
16257#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16258static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16259 struct net_device *dev,
16260 const u8 *peer, u8 action_code,
16261 u8 dialog_token, u16 status_code,
16262 u32 peer_capability, const u8 *buf,
16263 size_t len)
16264#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
16265static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16266 struct net_device *dev,
16267 u8 *peer, u8 action_code,
16268 u8 dialog_token,
16269 u16 status_code, u32 peer_capability,
16270 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016271#else
16272static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
16273 u8 *peer, u8 action_code, u8 dialog_token,
16274 u16 status_code, const u8 *buf, size_t len)
16275#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016276#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016277{
16278 int ret;
16279
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016280 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016281#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016282 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16283 dialog_token, status_code,
16284 peer_capability, buf, len);
16285#else /* TDLS_MGMT_VERSION2 */
16286#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
16287 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16288 dialog_token, status_code,
16289 peer_capability, initiator,
16290 buf, len);
16291#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
16292 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16293 dialog_token, status_code,
16294 peer_capability, buf, len);
16295#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
16296 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16297 dialog_token, status_code,
16298 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016299#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016300 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16301 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016302#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016303#endif
16304 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016305
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016306 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016307}
Atul Mittal115287b2014-07-08 13:26:33 +053016308
16309int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016310#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16311 const u8 *peer,
16312#else
Atul Mittal115287b2014-07-08 13:26:33 +053016313 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016314#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016315 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053016316 cfg80211_exttdls_callback callback)
16317{
16318
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016319 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053016320 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016321 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053016322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16323 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
16324 __func__, MAC_ADDR_ARRAY(peer));
16325
16326 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
16327 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
16328
16329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016330 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
16331 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
16332 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053016333 return -ENOTSUPP;
16334 }
16335
16336 /* To cater the requirement of establishing the TDLS link
16337 * irrespective of the data traffic , get an entry of TDLS peer.
16338 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053016339 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053016340 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
16341 if (pTdlsPeer == NULL) {
16342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16343 "%s: peer " MAC_ADDRESS_STR " not existing",
16344 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053016345 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053016346 return -EINVAL;
16347 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053016348 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053016349
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053016350 /* check FW TDLS Off Channel capability */
16351 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053016352 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053016353 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016354 {
16355 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
16356 pTdlsPeer->peerParams.global_operating_class =
16357 tdls_peer_params->global_operating_class;
16358 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
16359 pTdlsPeer->peerParams.min_bandwidth_kbps =
16360 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016361 /* check configured channel is valid, non dfs and
16362 * not current operating channel */
16363 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
16364 tdls_peer_params->channel)) &&
16365 (pHddStaCtx) &&
16366 (tdls_peer_params->channel !=
16367 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016368 {
16369 pTdlsPeer->isOffChannelConfigured = TRUE;
16370 }
16371 else
16372 {
16373 pTdlsPeer->isOffChannelConfigured = FALSE;
16374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16375 "%s: Configured Tdls Off Channel is not valid", __func__);
16376
16377 }
16378 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016379 "%s: tdls_off_channel %d isOffChannelConfigured %d "
16380 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016381 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016382 pTdlsPeer->isOffChannelConfigured,
16383 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016384 }
16385 else
16386 {
16387 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053016388 "%s: TDLS off channel FW capability %d, "
16389 "host capab %d or Invalid TDLS Peer Params", __func__,
16390 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
16391 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016392 }
16393
Atul Mittal115287b2014-07-08 13:26:33 +053016394 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
16395
16396 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16397 " %s TDLS Add Force Peer Failed",
16398 __func__);
16399 return -EINVAL;
16400 }
16401 /*EXT TDLS*/
16402
16403 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
16404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16405 " %s TDLS set callback Failed",
16406 __func__);
16407 return -EINVAL;
16408 }
16409
16410 return(0);
16411
16412}
16413
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016414int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
16415#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16416 const u8 *peer
16417#else
16418 u8 *peer
16419#endif
16420)
Atul Mittal115287b2014-07-08 13:26:33 +053016421{
16422
16423 hddTdlsPeer_t *pTdlsPeer;
16424 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16426 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
16427 __func__, MAC_ADDR_ARRAY(peer));
16428
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016429 if (0 != wlan_hdd_validate_context(pHddCtx)) {
16430 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
16431 return -EINVAL;
16432 }
16433
Atul Mittal115287b2014-07-08 13:26:33 +053016434 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
16435 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
16436
16437 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016438 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
16439 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
16440 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053016441 return -ENOTSUPP;
16442 }
16443
16444
16445 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
16446
16447 if ( NULL == pTdlsPeer ) {
16448 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016449 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053016450 __func__, MAC_ADDR_ARRAY(peer));
16451 return -EINVAL;
16452 }
16453 else {
16454 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
16455 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016456 /* if channel switch is configured, reset
16457 the channel for this peer */
16458 if (TRUE == pTdlsPeer->isOffChannelConfigured)
16459 {
16460 pTdlsPeer->peerParams.channel = 0;
16461 pTdlsPeer->isOffChannelConfigured = FALSE;
16462 }
Atul Mittal115287b2014-07-08 13:26:33 +053016463 }
16464
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016465 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
16466 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053016467 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016468 }
Atul Mittal115287b2014-07-08 13:26:33 +053016469
16470 /*EXT TDLS*/
16471
16472 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
16473
16474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16475 " %s TDLS set callback Failed",
16476 __func__);
16477 return -EINVAL;
16478 }
16479 return(0);
16480
16481}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016482static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016483#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16484 const u8 *peer,
16485#else
16486 u8 *peer,
16487#endif
16488 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016489{
16490 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16491 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016492 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016493 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016494
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016495 ENTER();
16496
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016497 if (!pAdapter) {
16498 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
16499 return -EINVAL;
16500 }
16501
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016502 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16503 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
16504 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016505 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016506 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016507 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070016508 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016509 return -EINVAL;
16510 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016511
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016512 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016513 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080016514 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016515 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080016516 }
16517
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016518
16519 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016520 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016521 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016522 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016523 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
16524 "Cannot process TDLS commands",
16525 pHddCtx->cfg_ini->fEnableTDLSSupport,
16526 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016527 return -ENOTSUPP;
16528 }
16529
16530 switch (oper) {
16531 case NL80211_TDLS_ENABLE_LINK:
16532 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016533 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016534 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016535 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053016536 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016537 tANI_U16 numCurrTdlsPeers = 0;
16538 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016539 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016540
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016541 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16542 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
16543 __func__, MAC_ADDR_ARRAY(peer));
Sunil Dutt41de4e22013-11-14 18:09:02 +053016544 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053016545 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053016546 if ( NULL == pTdlsPeer ) {
16547 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
16548 " (oper %d) not exsting. ignored",
16549 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
16550 return -EINVAL;
16551 }
16552
16553 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16554 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
16555 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
16556 "NL80211_TDLS_ENABLE_LINK");
16557
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070016558 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
16559 {
16560 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
16561 MAC_ADDRESS_STR " failed",
16562 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
16563 return -EINVAL;
16564 }
16565
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053016566 /* before starting tdls connection, set tdls
16567 * off channel established status to default value */
16568 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016569 /* TDLS Off Channel, Disable tdls channel switch,
16570 when there are more than one tdls link */
16571 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053016572 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016573 {
16574 /* get connected peer and send disable tdls off chan */
16575 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016576 if ((connPeer) &&
16577 (connPeer->isOffChannelSupported == TRUE) &&
16578 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016579 {
16580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16581 "%s: More then one peer connected, Disable "
16582 "TDLS channel switch", __func__);
16583
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016584 connPeer->isOffChannelEstablished = FALSE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016585 ret = sme_SendTdlsChanSwitchReq(
16586 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016587 pAdapter->sessionId,
16588 connPeer->peerMac,
16589 connPeer->peerParams.channel,
16590 TDLS_OFF_CHANNEL_BW_OFFSET,
16591 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016592 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016593 hddLog(VOS_TRACE_LEVEL_ERROR,
16594 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016595 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016596 }
16597 else
16598 {
16599 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16600 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016601 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016602 "isOffChannelConfigured %d",
16603 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016604 (connPeer ? (connPeer->isOffChannelSupported)
16605 : -1),
16606 (connPeer ? (connPeer->isOffChannelConfigured)
16607 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016608 }
16609 }
16610
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016611 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016612 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016613 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053016614
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016615 if (0 != wlan_hdd_tdls_get_link_establish_params(
16616 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016617 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016618 return -EINVAL;
16619 }
16620 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016621
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016622 ret = sme_SendTdlsLinkEstablishParams(
16623 WLAN_HDD_GET_HAL_CTX(pAdapter),
16624 pAdapter->sessionId, peer,
16625 &tdlsLinkEstablishParams);
16626 if (ret != VOS_STATUS_SUCCESS) {
16627 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
16628 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016629 /* Send TDLS peer UAPSD capabilities to the firmware and
16630 * register with the TL on after the response for this operation
16631 * is received .
16632 */
16633 ret = wait_for_completion_interruptible_timeout(
16634 &pAdapter->tdls_link_establish_req_comp,
16635 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
16636 if (ret <= 0)
16637 {
16638 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016639 FL("Link Establish Request Failed Status %ld"),
16640 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016641 return -EINVAL;
16642 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016643 }
Atul Mittal115287b2014-07-08 13:26:33 +053016644 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
16645 eTDLS_LINK_CONNECTED,
16646 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053016647 staDesc.ucSTAId = pTdlsPeer->staId;
16648 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016649 ret = WLANTL_UpdateTdlsSTAClient(
16650 pHddCtx->pvosContext,
16651 &staDesc);
16652 if (ret != VOS_STATUS_SUCCESS) {
16653 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
16654 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053016655
Gopichand Nakkala471708b2013-06-04 20:03:01 +053016656 /* Mark TDLS client Authenticated .*/
16657 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
16658 pTdlsPeer->staId,
16659 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070016660 if (VOS_STATUS_SUCCESS == status)
16661 {
Hoonki Lee14621352013-04-16 17:51:19 -070016662 if (pTdlsPeer->is_responder == 0)
16663 {
16664 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053016665 tdlsConnInfo_t *tdlsInfo;
16666
16667 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
16668
16669 /* Initialize initiator wait callback */
16670 vos_timer_init(
16671 &pTdlsPeer->initiatorWaitTimeoutTimer,
16672 VOS_TIMER_TYPE_SW,
16673 wlan_hdd_tdls_initiator_wait_cb,
16674 tdlsInfo);
Hoonki Lee14621352013-04-16 17:51:19 -070016675
16676 wlan_hdd_tdls_timer_restart(pAdapter,
16677 &pTdlsPeer->initiatorWaitTimeoutTimer,
16678 WAIT_TIME_TDLS_INITIATOR);
16679 /* suspend initiator TX until it receives direct packet from the
16680 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016681 ret = WLANTL_SuspendDataTx(
16682 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
16683 &staId, NULL);
16684 if (ret != VOS_STATUS_SUCCESS) {
16685 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
16686 }
Hoonki Lee14621352013-04-16 17:51:19 -070016687 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016688
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016689 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016690 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016691 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016692 suppChannelLen =
16693 tdlsLinkEstablishParams.supportedChannelsLen;
16694
16695 if ((suppChannelLen > 0) &&
16696 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
16697 {
16698 tANI_U8 suppPeerChannel = 0;
16699 int i = 0;
16700 for (i = 0U; i < suppChannelLen; i++)
16701 {
16702 suppPeerChannel =
16703 tdlsLinkEstablishParams.supportedChannels[i];
16704
16705 pTdlsPeer->isOffChannelSupported = FALSE;
16706 if (suppPeerChannel ==
16707 pTdlsPeer->peerParams.channel)
16708 {
16709 pTdlsPeer->isOffChannelSupported = TRUE;
16710 break;
16711 }
16712 }
16713 }
16714 else
16715 {
16716 pTdlsPeer->isOffChannelSupported = FALSE;
16717 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016718 }
16719 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16720 "%s: TDLS channel switch request for channel "
16721 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016722 "%d isOffChannelSupported %d", __func__,
16723 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016724 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016725 suppChannelLen,
16726 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016727
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016728 /* TDLS Off Channel, Enable tdls channel switch,
16729 when their is only one tdls link and it supports */
16730 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
16731 if ((numCurrTdlsPeers == 1) &&
16732 (TRUE == pTdlsPeer->isOffChannelSupported) &&
16733 (TRUE == pTdlsPeer->isOffChannelConfigured))
16734 {
16735 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16736 "%s: Send TDLS channel switch request for channel %d",
16737 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016738
16739 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016740 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
16741 pAdapter->sessionId,
16742 pTdlsPeer->peerMac,
16743 pTdlsPeer->peerParams.channel,
16744 TDLS_OFF_CHANNEL_BW_OFFSET,
16745 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016746 if (ret != VOS_STATUS_SUCCESS) {
16747 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
16748 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016749 }
16750 else
16751 {
16752 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16753 "%s: TDLS channel switch request not sent"
16754 " numCurrTdlsPeers %d "
16755 "isOffChannelSupported %d "
16756 "isOffChannelConfigured %d",
16757 __func__, numCurrTdlsPeers,
16758 pTdlsPeer->isOffChannelSupported,
16759 pTdlsPeer->isOffChannelConfigured);
16760 }
16761
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070016762 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016763 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016764
16765 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016766 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
16767 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016768 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016769 int ac;
16770 uint8 ucAc[4] = { WLANTL_AC_VO,
16771 WLANTL_AC_VI,
16772 WLANTL_AC_BK,
16773 WLANTL_AC_BE };
16774 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
16775 for(ac=0; ac < 4; ac++)
16776 {
16777 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
16778 pTdlsPeer->staId, ucAc[ac],
16779 tlTid[ac], tlTid[ac], 0, 0,
16780 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016781 if (status != VOS_STATUS_SUCCESS) {
16782 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
16783 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016784 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016785 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016786 }
16787
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016788 }
16789 break;
16790 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080016791 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016792 tANI_U16 numCurrTdlsPeers = 0;
16793 hddTdlsPeer_t *connPeer = NULL;
16794
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16796 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
16797 __func__, MAC_ADDR_ARRAY(peer));
16798
Sunil Dutt41de4e22013-11-14 18:09:02 +053016799 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
16800
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016801
Sunil Dutt41de4e22013-11-14 18:09:02 +053016802 if ( NULL == pTdlsPeer ) {
16803 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
16804 " (oper %d) not exsting. ignored",
16805 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
16806 return -EINVAL;
16807 }
16808
16809 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16810 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
16811 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
16812 "NL80211_TDLS_DISABLE_LINK");
16813
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016814 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080016815 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016816 long status;
16817
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053016818 /* set tdls off channel status to false for this peer */
16819 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053016820 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
16821 eTDLS_LINK_TEARING,
16822 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
16823 eTDLS_LINK_UNSPECIFIED:
16824 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016825 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
16826
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016827 status = sme_DeleteTdlsPeerSta(
16828 WLAN_HDD_GET_HAL_CTX(pAdapter),
16829 pAdapter->sessionId, peer );
16830 if (status != VOS_STATUS_SUCCESS) {
16831 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
16832 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016833
16834 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
16835 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053016836 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053016837 eTDLS_LINK_IDLE,
16838 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016839 if (status <= 0)
16840 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016841 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16842 "%s: Del station failed status %ld",
16843 __func__, status);
16844 return -EPERM;
16845 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016846
16847 /* TDLS Off Channel, Enable tdls channel switch,
16848 when their is only one tdls link and it supports */
16849 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
16850 if (numCurrTdlsPeers == 1)
16851 {
16852 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
16853 if ((connPeer) &&
16854 (connPeer->isOffChannelSupported == TRUE) &&
16855 (connPeer->isOffChannelConfigured == TRUE))
16856 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016857 connPeer->isOffChannelEstablished = TRUE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016858 status = sme_SendTdlsChanSwitchReq(
16859 WLAN_HDD_GET_HAL_CTX(pAdapter),
16860 pAdapter->sessionId,
16861 connPeer->peerMac,
16862 connPeer->peerParams.channel,
16863 TDLS_OFF_CHANNEL_BW_OFFSET,
16864 TDLS_CHANNEL_SWITCH_ENABLE);
16865 if (status != VOS_STATUS_SUCCESS) {
16866 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
16867 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016868 }
16869 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16870 "%s: TDLS channel switch "
16871 "isOffChannelSupported %d "
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016872 "isOffChannelConfigured %d "
16873 "isOffChannelEstablished %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016874 __func__,
16875 (connPeer ? connPeer->isOffChannelSupported : -1),
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016876 (connPeer ? connPeer->isOffChannelConfigured : -1),
16877 (connPeer ? connPeer->isOffChannelEstablished : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016878 }
16879 else
16880 {
16881 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16882 "%s: TDLS channel switch request not sent "
16883 "numCurrTdlsPeers %d ",
16884 __func__, numCurrTdlsPeers);
16885 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080016886 }
16887 else
16888 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016889 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16890 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080016891 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080016892 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016893 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016894 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053016895 {
Atul Mittal115287b2014-07-08 13:26:33 +053016896 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053016897
Atul Mittal115287b2014-07-08 13:26:33 +053016898 if (0 != status)
16899 {
16900 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016901 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053016902 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053016903 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053016904 break;
16905 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016906 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053016907 {
Atul Mittal115287b2014-07-08 13:26:33 +053016908 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
16909 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016910 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053016911 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053016912
Atul Mittal115287b2014-07-08 13:26:33 +053016913 if (0 != status)
16914 {
16915 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016916 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053016917 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053016918 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053016919 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053016920 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016921 case NL80211_TDLS_DISCOVERY_REQ:
16922 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016923 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016924 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016925 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016926 return -ENOTSUPP;
16927 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016928 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16929 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016930 return -ENOTSUPP;
16931 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016932
16933 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016934 return 0;
16935}
Chilam NG571c65a2013-01-19 12:27:36 +053016936
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016937static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016938#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16939 const u8 *peer,
16940#else
16941 u8 *peer,
16942#endif
16943 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016944{
16945 int ret;
16946
16947 vos_ssr_protect(__func__);
16948 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
16949 vos_ssr_unprotect(__func__);
16950
16951 return ret;
16952}
16953
Chilam NG571c65a2013-01-19 12:27:36 +053016954int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
16955 struct net_device *dev, u8 *peer)
16956{
Arif Hussaina7c8e412013-11-20 11:06:42 -080016957 hddLog(VOS_TRACE_LEVEL_INFO,
16958 "tdls send discover req: "MAC_ADDRESS_STR,
16959 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053016960
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016961#if TDLS_MGMT_VERSION2
16962 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16963 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16964#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016965#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
16966 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16967 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
16968#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16969 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16970 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16971#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
16972 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16973 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16974#else
Chilam NG571c65a2013-01-19 12:27:36 +053016975 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16976 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016977#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016978#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053016979}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016980#endif
16981
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016982#ifdef WLAN_FEATURE_GTK_OFFLOAD
16983/*
16984 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
16985 * Callback rountine called upon receiving response for
16986 * get offload info
16987 */
16988void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
16989 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
16990{
16991
16992 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016993 tANI_U8 tempReplayCounter[8];
16994 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016995
16996 ENTER();
16997
16998 if (NULL == pAdapter)
16999 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053017000 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017001 "%s: HDD adapter is Null", __func__);
17002 return ;
17003 }
17004
17005 if (NULL == pGtkOffloadGetInfoRsp)
17006 {
17007 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17008 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
17009 return ;
17010 }
17011
17012 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
17013 {
17014 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17015 "%s: wlan Failed to get replay counter value",
17016 __func__);
17017 return ;
17018 }
17019
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017020 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17021 /* Update replay counter */
17022 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
17023 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
17024
17025 {
17026 /* changing from little to big endian since supplicant
17027 * works on big endian format
17028 */
17029 int i;
17030 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
17031
17032 for (i = 0; i < 8; i++)
17033 {
17034 tempReplayCounter[7-i] = (tANI_U8)p[i];
17035 }
17036 }
17037
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017038 /* Update replay counter to NL */
17039 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017040 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017041}
17042
17043/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017044 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017045 * This function is used to offload GTK rekeying job to the firmware.
17046 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017047int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017048 struct cfg80211_gtk_rekey_data *data)
17049{
17050 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17051 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17052 hdd_station_ctx_t *pHddStaCtx;
17053 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017054 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017055 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017056 eHalStatus status = eHAL_STATUS_FAILURE;
17057
17058 ENTER();
17059
17060 if (NULL == pAdapter)
17061 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053017062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017063 "%s: HDD adapter is Null", __func__);
17064 return -ENODEV;
17065 }
17066
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053017067 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17068 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
17069 pAdapter->sessionId, pAdapter->device_mode));
17070
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017071 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017072 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017073 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053017074 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017075 }
17076
17077 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17078 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
17079 if (NULL == hHal)
17080 {
17081 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17082 "%s: HAL context is Null!!!", __func__);
17083 return -EAGAIN;
17084 }
17085
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017086 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
17087 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
17088 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
17089 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017090 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017091 {
17092 /* changing from big to little endian since driver
17093 * works on little endian format
17094 */
17095 tANI_U8 *p =
17096 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
17097 int i;
17098
17099 for (i = 0; i < 8; i++)
17100 {
17101 p[7-i] = data->replay_ctr[i];
17102 }
17103 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017104
17105 if (TRUE == pHddCtx->hdd_wlan_suspended)
17106 {
17107 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017108 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
17109 sizeof (tSirGtkOffloadParams));
17110 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017111 pAdapter->sessionId);
17112
17113 if (eHAL_STATUS_SUCCESS != status)
17114 {
17115 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17116 "%s: sme_SetGTKOffload failed, returned %d",
17117 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053017118
17119 /* Need to clear any trace of key value in the memory.
17120 * Thus zero out the memory even though it is local
17121 * variable.
17122 */
17123 vos_mem_zero(&hddGtkOffloadReqParams,
17124 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017125 return status;
17126 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017127 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17128 "%s: sme_SetGTKOffload successfull", __func__);
17129 }
17130 else
17131 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017132 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17133 "%s: wlan not suspended GTKOffload request is stored",
17134 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017135 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017136
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053017137 /* Need to clear any trace of key value in the memory.
17138 * Thus zero out the memory even though it is local
17139 * variable.
17140 */
17141 vos_mem_zero(&hddGtkOffloadReqParams,
17142 sizeof(hddGtkOffloadReqParams));
17143
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017144 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053017145 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017146}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017147
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017148int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
17149 struct cfg80211_gtk_rekey_data *data)
17150{
17151 int ret;
17152
17153 vos_ssr_protect(__func__);
17154 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
17155 vos_ssr_unprotect(__func__);
17156
17157 return ret;
17158}
17159#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017160/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017161 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017162 * This function is used to set access control policy
17163 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017164static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
17165 struct net_device *dev,
17166 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017167{
17168 int i;
17169 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17170 hdd_hostapd_state_t *pHostapdState;
17171 tsap_Config_t *pConfig;
17172 v_CONTEXT_t pVosContext = NULL;
17173 hdd_context_t *pHddCtx;
17174 int status;
17175
17176 ENTER();
17177
17178 if (NULL == pAdapter)
17179 {
17180 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17181 "%s: HDD adapter is Null", __func__);
17182 return -ENODEV;
17183 }
17184
17185 if (NULL == params)
17186 {
17187 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17188 "%s: params is Null", __func__);
17189 return -EINVAL;
17190 }
17191
17192 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17193 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017194 if (0 != status)
17195 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017196 return status;
17197 }
17198
17199 pVosContext = pHddCtx->pvosContext;
17200 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
17201
17202 if (NULL == pHostapdState)
17203 {
17204 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17205 "%s: pHostapdState is Null", __func__);
17206 return -EINVAL;
17207 }
17208
17209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
17210 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017211 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17212 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
17213 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017214
17215 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
17216 {
17217 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
17218
17219 /* default value */
17220 pConfig->num_accept_mac = 0;
17221 pConfig->num_deny_mac = 0;
17222
17223 /**
17224 * access control policy
17225 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
17226 * listed in hostapd.deny file.
17227 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
17228 * listed in hostapd.accept file.
17229 */
17230 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
17231 {
17232 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
17233 }
17234 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
17235 {
17236 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
17237 }
17238 else
17239 {
17240 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17241 "%s:Acl Policy : %d is not supported",
17242 __func__, params->acl_policy);
17243 return -ENOTSUPP;
17244 }
17245
17246 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
17247 {
17248 pConfig->num_accept_mac = params->n_acl_entries;
17249 for (i = 0; i < params->n_acl_entries; i++)
17250 {
17251 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17252 "** Add ACL MAC entry %i in WhiletList :"
17253 MAC_ADDRESS_STR, i,
17254 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
17255
17256 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
17257 sizeof(qcmacaddr));
17258 }
17259 }
17260 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
17261 {
17262 pConfig->num_deny_mac = params->n_acl_entries;
17263 for (i = 0; i < params->n_acl_entries; i++)
17264 {
17265 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17266 "** Add ACL MAC entry %i in BlackList :"
17267 MAC_ADDRESS_STR, i,
17268 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
17269
17270 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
17271 sizeof(qcmacaddr));
17272 }
17273 }
17274
17275 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
17276 {
17277 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17278 "%s: SAP Set Mac Acl fail", __func__);
17279 return -EINVAL;
17280 }
17281 }
17282 else
17283 {
17284 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017285 "%s: Invalid device_mode = %s (%d)",
17286 __func__, hdd_device_modetoString(pAdapter->device_mode),
17287 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017288 return -EINVAL;
17289 }
17290
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017291 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017292 return 0;
17293}
17294
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017295static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
17296 struct net_device *dev,
17297 const struct cfg80211_acl_data *params)
17298{
17299 int ret;
17300 vos_ssr_protect(__func__);
17301 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
17302 vos_ssr_unprotect(__func__);
17303
17304 return ret;
17305}
17306
Leo Chang9056f462013-08-01 19:21:11 -070017307#ifdef WLAN_NL80211_TESTMODE
17308#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070017309void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070017310(
17311 void *pAdapter,
17312 void *indCont
17313)
17314{
Leo Changd9df8aa2013-09-26 13:32:26 -070017315 tSirLPHBInd *lphbInd;
17316 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053017317 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070017318
17319 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070017320 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070017321
c_hpothu73f35e62014-04-18 13:40:08 +053017322 if (pAdapter == NULL)
17323 {
17324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17325 "%s: pAdapter is NULL\n",__func__);
17326 return;
17327 }
17328
Leo Chang9056f462013-08-01 19:21:11 -070017329 if (NULL == indCont)
17330 {
17331 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070017332 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070017333 return;
17334 }
17335
c_hpothu73f35e62014-04-18 13:40:08 +053017336 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070017337 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070017338 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053017339 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070017340 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070017341 GFP_ATOMIC);
17342 if (!skb)
17343 {
17344 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17345 "LPHB timeout, NL buffer alloc fail");
17346 return;
17347 }
17348
Leo Changac3ba772013-10-07 09:47:04 -070017349 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070017350 {
17351 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17352 "WLAN_HDD_TM_ATTR_CMD put fail");
17353 goto nla_put_failure;
17354 }
Leo Changac3ba772013-10-07 09:47:04 -070017355 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070017356 {
17357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17358 "WLAN_HDD_TM_ATTR_TYPE put fail");
17359 goto nla_put_failure;
17360 }
Leo Changac3ba772013-10-07 09:47:04 -070017361 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070017362 sizeof(tSirLPHBInd), lphbInd))
17363 {
17364 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17365 "WLAN_HDD_TM_ATTR_DATA put fail");
17366 goto nla_put_failure;
17367 }
Leo Chang9056f462013-08-01 19:21:11 -070017368 cfg80211_testmode_event(skb, GFP_ATOMIC);
17369 return;
17370
17371nla_put_failure:
17372 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17373 "NLA Put fail");
17374 kfree_skb(skb);
17375
17376 return;
17377}
17378#endif /* FEATURE_WLAN_LPHB */
17379
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017380static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070017381{
17382 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
17383 int err = 0;
17384#ifdef FEATURE_WLAN_LPHB
17385 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070017386 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017387
17388 ENTER();
17389
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017390 err = wlan_hdd_validate_context(pHddCtx);
17391 if (0 != err)
17392 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017393 return err;
17394 }
Leo Chang9056f462013-08-01 19:21:11 -070017395#endif /* FEATURE_WLAN_LPHB */
17396
17397 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
17398 if (err)
17399 {
17400 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17401 "%s Testmode INV ATTR", __func__);
17402 return err;
17403 }
17404
17405 if (!tb[WLAN_HDD_TM_ATTR_CMD])
17406 {
17407 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17408 "%s Testmode INV CMD", __func__);
17409 return -EINVAL;
17410 }
17411
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017412 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17413 TRACE_CODE_HDD_CFG80211_TESTMODE,
17414 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070017415 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
17416 {
17417#ifdef FEATURE_WLAN_LPHB
17418 /* Low Power Heartbeat configuration request */
17419 case WLAN_HDD_TM_CMD_WLAN_HB:
17420 {
17421 int buf_len;
17422 void *buf;
17423 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080017424 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070017425
17426 if (!tb[WLAN_HDD_TM_ATTR_DATA])
17427 {
17428 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17429 "%s Testmode INV DATA", __func__);
17430 return -EINVAL;
17431 }
17432
17433 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
17434 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080017435
17436 hb_params_temp =(tSirLPHBReq *)buf;
17437 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
17438 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
17439 return -EINVAL;
17440
Leo Chang9056f462013-08-01 19:21:11 -070017441 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
17442 if (NULL == hb_params)
17443 {
17444 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17445 "%s Request Buffer Alloc Fail", __func__);
17446 return -EINVAL;
17447 }
17448
17449 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070017450 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
17451 hb_params,
17452 wlan_hdd_cfg80211_lphb_ind_handler);
17453 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070017454 {
Leo Changd9df8aa2013-09-26 13:32:26 -070017455 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17456 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070017457 vos_mem_free(hb_params);
17458 }
Leo Chang9056f462013-08-01 19:21:11 -070017459 return 0;
17460 }
17461#endif /* FEATURE_WLAN_LPHB */
17462 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017463 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17464 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070017465 return -EOPNOTSUPP;
17466 }
17467
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017468 EXIT();
17469 return err;
Leo Chang9056f462013-08-01 19:21:11 -070017470}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017471
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053017472static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
17473#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
17474 struct wireless_dev *wdev,
17475#endif
17476 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017477{
17478 int ret;
17479
17480 vos_ssr_protect(__func__);
17481 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
17482 vos_ssr_unprotect(__func__);
17483
17484 return ret;
17485}
Leo Chang9056f462013-08-01 19:21:11 -070017486#endif /* CONFIG_NL80211_TESTMODE */
17487
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017488static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017489 struct net_device *dev,
17490 int idx, struct survey_info *survey)
17491{
17492 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17493 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053017494 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017495 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053017496 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017497 v_S7_t snr,rssi;
17498 int status, i, j, filled = 0;
17499
17500 ENTER();
17501
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017502 if (NULL == pAdapter)
17503 {
17504 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17505 "%s: HDD adapter is Null", __func__);
17506 return -ENODEV;
17507 }
17508
17509 if (NULL == wiphy)
17510 {
17511 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17512 "%s: wiphy is Null", __func__);
17513 return -ENODEV;
17514 }
17515
17516 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17517 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017518 if (0 != status)
17519 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017520 return status;
17521 }
17522
Mihir Sheted9072e02013-08-21 17:02:29 +053017523 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17524
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017525 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053017526 0 != pAdapter->survey_idx ||
17527 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017528 {
17529 /* The survey dump ops when implemented completely is expected to
17530 * return a survey of all channels and the ops is called by the
17531 * kernel with incremental values of the argument 'idx' till it
17532 * returns -ENONET. But we can only support the survey for the
17533 * operating channel for now. survey_idx is used to track
17534 * that the ops is called only once and then return -ENONET for
17535 * the next iteration
17536 */
17537 pAdapter->survey_idx = 0;
17538 return -ENONET;
17539 }
17540
Mukul Sharma9d5233b2015-06-11 20:28:20 +053017541 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
17542 {
17543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17544 "%s: Roaming in progress, hence return ", __func__);
17545 return -ENONET;
17546 }
17547
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017548 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17549
17550 wlan_hdd_get_snr(pAdapter, &snr);
17551 wlan_hdd_get_rssi(pAdapter, &rssi);
17552
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017553 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17554 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
17555 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017556 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
17557 hdd_wlan_get_freq(channel, &freq);
17558
17559
17560 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
17561 {
17562 if (NULL == wiphy->bands[i])
17563 {
17564 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
17565 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
17566 continue;
17567 }
17568
17569 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
17570 {
17571 struct ieee80211_supported_band *band = wiphy->bands[i];
17572
17573 if (band->channels[j].center_freq == (v_U16_t)freq)
17574 {
17575 survey->channel = &band->channels[j];
17576 /* The Rx BDs contain SNR values in dB for the received frames
17577 * while the supplicant expects noise. So we calculate and
17578 * return the value of noise (dBm)
17579 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
17580 */
17581 survey->noise = rssi - snr;
17582 survey->filled = SURVEY_INFO_NOISE_DBM;
17583 filled = 1;
17584 }
17585 }
17586 }
17587
17588 if (filled)
17589 pAdapter->survey_idx = 1;
17590 else
17591 {
17592 pAdapter->survey_idx = 0;
17593 return -ENONET;
17594 }
17595
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017596 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017597 return 0;
17598}
17599
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017600static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
17601 struct net_device *dev,
17602 int idx, struct survey_info *survey)
17603{
17604 int ret;
17605
17606 vos_ssr_protect(__func__);
17607 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
17608 vos_ssr_unprotect(__func__);
17609
17610 return ret;
17611}
17612
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017613/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017614 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017615 * this is called when cfg80211 driver resume
17616 * driver updates latest sched_scan scan result(if any) to cfg80211 database
17617 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017618int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017619{
17620 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17621 hdd_adapter_t *pAdapter;
17622 hdd_adapter_list_node_t *pAdapterNode, *pNext;
17623 VOS_STATUS status = VOS_STATUS_SUCCESS;
17624
17625 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017626
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017627 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017628 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017629 return 0;
17630 }
17631
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017632 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
17633 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017634 spin_lock(&pHddCtx->schedScan_lock);
17635 pHddCtx->isWiphySuspended = FALSE;
17636 if (TRUE != pHddCtx->isSchedScanUpdatePending)
17637 {
17638 spin_unlock(&pHddCtx->schedScan_lock);
17639 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17640 "%s: Return resume is not due to PNO indication", __func__);
17641 return 0;
17642 }
17643 // Reset flag to avoid updatating cfg80211 data old results again
17644 pHddCtx->isSchedScanUpdatePending = FALSE;
17645 spin_unlock(&pHddCtx->schedScan_lock);
17646
17647 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
17648
17649 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
17650 {
17651 pAdapter = pAdapterNode->pAdapter;
17652 if ( (NULL != pAdapter) &&
17653 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
17654 {
17655 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017656 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
17658 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017659 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017660 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017661 {
17662 /* Acquire wakelock to handle the case where APP's tries to
17663 * suspend immediately after updating the scan results. Whis
17664 * results in app's is in suspended state and not able to
17665 * process the connect request to AP
17666 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053017667 hdd_prevent_suspend_timeout(2000,
17668 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017669 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017670 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017671
17672 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17673 "%s : cfg80211 scan result database updated", __func__);
17674
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017675 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017676 return 0;
17677
17678 }
17679 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
17680 pAdapterNode = pNext;
17681 }
17682
17683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17684 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017685 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017686 return 0;
17687}
17688
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017689int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
17690{
17691 int ret;
17692
17693 vos_ssr_protect(__func__);
17694 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
17695 vos_ssr_unprotect(__func__);
17696
17697 return ret;
17698}
17699
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017700/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017701 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017702 * this is called when cfg80211 driver suspends
17703 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017704int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017705 struct cfg80211_wowlan *wow)
17706{
17707 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017708 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017709
17710 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017711
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017712 ret = wlan_hdd_validate_context(pHddCtx);
17713 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017714 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017715 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017716 }
17717
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017718
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017719 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17720 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
17721 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017722 pHddCtx->isWiphySuspended = TRUE;
17723
17724 EXIT();
17725
17726 return 0;
17727}
17728
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017729int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
17730 struct cfg80211_wowlan *wow)
17731{
17732 int ret;
17733
17734 vos_ssr_protect(__func__);
17735 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
17736 vos_ssr_unprotect(__func__);
17737
17738 return ret;
17739}
Jeff Johnson295189b2012-06-20 16:38:30 -070017740/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017741static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070017742{
17743 .add_virtual_intf = wlan_hdd_add_virtual_intf,
17744 .del_virtual_intf = wlan_hdd_del_virtual_intf,
17745 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
17746 .change_station = wlan_hdd_change_station,
17747#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
17748 .add_beacon = wlan_hdd_cfg80211_add_beacon,
17749 .del_beacon = wlan_hdd_cfg80211_del_beacon,
17750 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017751#else
17752 .start_ap = wlan_hdd_cfg80211_start_ap,
17753 .change_beacon = wlan_hdd_cfg80211_change_beacon,
17754 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070017755#endif
17756 .change_bss = wlan_hdd_cfg80211_change_bss,
17757 .add_key = wlan_hdd_cfg80211_add_key,
17758 .get_key = wlan_hdd_cfg80211_get_key,
17759 .del_key = wlan_hdd_cfg80211_del_key,
17760 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080017761#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070017762 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080017763#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017764 .scan = wlan_hdd_cfg80211_scan,
17765 .connect = wlan_hdd_cfg80211_connect,
17766 .disconnect = wlan_hdd_cfg80211_disconnect,
17767 .join_ibss = wlan_hdd_cfg80211_join_ibss,
17768 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
17769 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
17770 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
17771 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070017772 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
17773 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053017774 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070017775#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17776 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
17777 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
17778 .set_txq_params = wlan_hdd_set_txq_params,
17779#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017780 .get_station = wlan_hdd_cfg80211_get_station,
17781 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
17782 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017783 .add_station = wlan_hdd_cfg80211_add_station,
17784#ifdef FEATURE_WLAN_LFR
17785 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
17786 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
17787 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
17788#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017789#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
17790 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
17791#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017792#ifdef FEATURE_WLAN_TDLS
17793 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
17794 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
17795#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017796#ifdef WLAN_FEATURE_GTK_OFFLOAD
17797 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
17798#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017799#ifdef FEATURE_WLAN_SCAN_PNO
17800 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
17801 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
17802#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017803 .resume = wlan_hdd_cfg80211_resume_wlan,
17804 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017805 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070017806#ifdef WLAN_NL80211_TESTMODE
17807 .testmode_cmd = wlan_hdd_cfg80211_testmode,
17808#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017809 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070017810};
17811