blob: 12ed8ab9cb330ad7c294c08343f7933ba30936b4 [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"
Jeff Johnson295189b2012-06-20 16:38:30 -070098
99#define g_mode_rates_size (12)
100#define a_mode_rates_size (8)
101#define FREQ_BASE_80211G (2407)
102#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700103#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530104#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700105#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800106 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700107
108#define HDD2GHZCHAN(freq, chan, flag) { \
109 .band = IEEE80211_BAND_2GHZ, \
110 .center_freq = (freq), \
111 .hw_value = (chan),\
112 .flags = (flag), \
113 .max_antenna_gain = 0 ,\
114 .max_power = 30, \
115}
116
117#define HDD5GHZCHAN(freq, chan, flag) { \
118 .band = IEEE80211_BAND_5GHZ, \
119 .center_freq = (freq), \
120 .hw_value = (chan),\
121 .flags = (flag), \
122 .max_antenna_gain = 0 ,\
123 .max_power = 30, \
124}
125
126#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
127{\
128 .bitrate = rate, \
129 .hw_value = rate_id, \
130 .flags = flag, \
131}
132
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530133#ifdef WLAN_FEATURE_VOWIFI_11R
134#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
135#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
136#endif
137
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530138#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530139#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530140
Sunil Duttc69bccb2014-05-26 21:30:20 +0530141#ifdef WLAN_FEATURE_LINK_LAYER_STATS
142/*
143 * Used to allocate the size of 4096 for the link layer stats.
144 * The size of 4096 is considered assuming that all data per
145 * respective event fit with in the limit.Please take a call
146 * on the limit based on the data requirements on link layer
147 * statistics.
148 */
149#define LL_STATS_EVENT_BUF_SIZE 4096
150#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530151#ifdef WLAN_FEATURE_EXTSCAN
152/*
153 * Used to allocate the size of 4096 for the EXTScan NL data.
154 * The size of 4096 is considered assuming that all data per
155 * respective event fit with in the limit.Please take a call
156 * on the limit based on the data requirements.
157 */
158
159#define EXTSCAN_EVENT_BUF_SIZE 4096
160#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
161#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530162
Atul Mittal115287b2014-07-08 13:26:33 +0530163/*EXT TDLS*/
164/*
165 * Used to allocate the size of 4096 for the TDLS.
166 * The size of 4096 is considered assuming that all data per
167 * respective event fit with in the limit.Please take a call
168 * on the limit based on the data requirements on link layer
169 * statistics.
170 */
171#define EXTTDLS_EVENT_BUF_SIZE 4096
172
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530173static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700174{
175 WLAN_CIPHER_SUITE_WEP40,
176 WLAN_CIPHER_SUITE_WEP104,
177 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800178#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700179#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
180 WLAN_CIPHER_SUITE_KRK,
181 WLAN_CIPHER_SUITE_CCMP,
182#else
183 WLAN_CIPHER_SUITE_CCMP,
184#endif
185#ifdef FEATURE_WLAN_WAPI
186 WLAN_CIPHER_SUITE_SMS4,
187#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700188#ifdef WLAN_FEATURE_11W
189 WLAN_CIPHER_SUITE_AES_CMAC,
190#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700191};
192
193static inline int is_broadcast_ether_addr(const u8 *addr)
194{
195 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
196 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
197}
198
199static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530200{
Jeff Johnson295189b2012-06-20 16:38:30 -0700201 HDD2GHZCHAN(2412, 1, 0) ,
202 HDD2GHZCHAN(2417, 2, 0) ,
203 HDD2GHZCHAN(2422, 3, 0) ,
204 HDD2GHZCHAN(2427, 4, 0) ,
205 HDD2GHZCHAN(2432, 5, 0) ,
206 HDD2GHZCHAN(2437, 6, 0) ,
207 HDD2GHZCHAN(2442, 7, 0) ,
208 HDD2GHZCHAN(2447, 8, 0) ,
209 HDD2GHZCHAN(2452, 9, 0) ,
210 HDD2GHZCHAN(2457, 10, 0) ,
211 HDD2GHZCHAN(2462, 11, 0) ,
212 HDD2GHZCHAN(2467, 12, 0) ,
213 HDD2GHZCHAN(2472, 13, 0) ,
214 HDD2GHZCHAN(2484, 14, 0) ,
215};
216
Jeff Johnson295189b2012-06-20 16:38:30 -0700217static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
218{
219 HDD2GHZCHAN(2412, 1, 0) ,
220 HDD2GHZCHAN(2437, 6, 0) ,
221 HDD2GHZCHAN(2462, 11, 0) ,
222};
Jeff Johnson295189b2012-06-20 16:38:30 -0700223
224static struct ieee80211_channel hdd_channels_5_GHZ[] =
225{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700226 HDD5GHZCHAN(4920, 240, 0) ,
227 HDD5GHZCHAN(4940, 244, 0) ,
228 HDD5GHZCHAN(4960, 248, 0) ,
229 HDD5GHZCHAN(4980, 252, 0) ,
230 HDD5GHZCHAN(5040, 208, 0) ,
231 HDD5GHZCHAN(5060, 212, 0) ,
232 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700233 HDD5GHZCHAN(5180, 36, 0) ,
234 HDD5GHZCHAN(5200, 40, 0) ,
235 HDD5GHZCHAN(5220, 44, 0) ,
236 HDD5GHZCHAN(5240, 48, 0) ,
237 HDD5GHZCHAN(5260, 52, 0) ,
238 HDD5GHZCHAN(5280, 56, 0) ,
239 HDD5GHZCHAN(5300, 60, 0) ,
240 HDD5GHZCHAN(5320, 64, 0) ,
241 HDD5GHZCHAN(5500,100, 0) ,
242 HDD5GHZCHAN(5520,104, 0) ,
243 HDD5GHZCHAN(5540,108, 0) ,
244 HDD5GHZCHAN(5560,112, 0) ,
245 HDD5GHZCHAN(5580,116, 0) ,
246 HDD5GHZCHAN(5600,120, 0) ,
247 HDD5GHZCHAN(5620,124, 0) ,
248 HDD5GHZCHAN(5640,128, 0) ,
249 HDD5GHZCHAN(5660,132, 0) ,
250 HDD5GHZCHAN(5680,136, 0) ,
251 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800252#ifdef FEATURE_WLAN_CH144
253 HDD5GHZCHAN(5720,144, 0) ,
254#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700255 HDD5GHZCHAN(5745,149, 0) ,
256 HDD5GHZCHAN(5765,153, 0) ,
257 HDD5GHZCHAN(5785,157, 0) ,
258 HDD5GHZCHAN(5805,161, 0) ,
259 HDD5GHZCHAN(5825,165, 0) ,
260};
261
262static struct ieee80211_rate g_mode_rates[] =
263{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530264 HDD_G_MODE_RATETAB(10, 0x1, 0),
265 HDD_G_MODE_RATETAB(20, 0x2, 0),
266 HDD_G_MODE_RATETAB(55, 0x4, 0),
267 HDD_G_MODE_RATETAB(110, 0x8, 0),
268 HDD_G_MODE_RATETAB(60, 0x10, 0),
269 HDD_G_MODE_RATETAB(90, 0x20, 0),
270 HDD_G_MODE_RATETAB(120, 0x40, 0),
271 HDD_G_MODE_RATETAB(180, 0x80, 0),
272 HDD_G_MODE_RATETAB(240, 0x100, 0),
273 HDD_G_MODE_RATETAB(360, 0x200, 0),
274 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700275 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530276};
Jeff Johnson295189b2012-06-20 16:38:30 -0700277
278static struct ieee80211_rate a_mode_rates[] =
279{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530280 HDD_G_MODE_RATETAB(60, 0x10, 0),
281 HDD_G_MODE_RATETAB(90, 0x20, 0),
282 HDD_G_MODE_RATETAB(120, 0x40, 0),
283 HDD_G_MODE_RATETAB(180, 0x80, 0),
284 HDD_G_MODE_RATETAB(240, 0x100, 0),
285 HDD_G_MODE_RATETAB(360, 0x200, 0),
286 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700287 HDD_G_MODE_RATETAB(540, 0x800, 0),
288};
289
290static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
291{
292 .channels = hdd_channels_2_4_GHZ,
293 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
294 .band = IEEE80211_BAND_2GHZ,
295 .bitrates = g_mode_rates,
296 .n_bitrates = g_mode_rates_size,
297 .ht_cap.ht_supported = 1,
298 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
299 | IEEE80211_HT_CAP_GRN_FLD
300 | IEEE80211_HT_CAP_DSSSCCK40
301 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
302 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
303 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
304 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
305 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
306 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
307};
308
Jeff Johnson295189b2012-06-20 16:38:30 -0700309static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
310{
311 .channels = hdd_social_channels_2_4_GHZ,
312 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
313 .band = IEEE80211_BAND_2GHZ,
314 .bitrates = g_mode_rates,
315 .n_bitrates = g_mode_rates_size,
316 .ht_cap.ht_supported = 1,
317 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
318 | IEEE80211_HT_CAP_GRN_FLD
319 | IEEE80211_HT_CAP_DSSSCCK40
320 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
321 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
322 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
323 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
324 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
325 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
326};
Jeff Johnson295189b2012-06-20 16:38:30 -0700327
328static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
329{
330 .channels = hdd_channels_5_GHZ,
331 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
332 .band = IEEE80211_BAND_5GHZ,
333 .bitrates = a_mode_rates,
334 .n_bitrates = a_mode_rates_size,
335 .ht_cap.ht_supported = 1,
336 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
337 | IEEE80211_HT_CAP_GRN_FLD
338 | IEEE80211_HT_CAP_DSSSCCK40
339 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
340 | IEEE80211_HT_CAP_SGI_40
341 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
342 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
343 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
344 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
345 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
346 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
347};
348
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530349/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700350 TX/RX direction for each kind of interface */
351static const struct ieee80211_txrx_stypes
352wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
353 [NL80211_IFTYPE_STATION] = {
354 .tx = 0xffff,
355 .rx = BIT(SIR_MAC_MGMT_ACTION) |
356 BIT(SIR_MAC_MGMT_PROBE_REQ),
357 },
358 [NL80211_IFTYPE_AP] = {
359 .tx = 0xffff,
360 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
361 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
362 BIT(SIR_MAC_MGMT_PROBE_REQ) |
363 BIT(SIR_MAC_MGMT_DISASSOC) |
364 BIT(SIR_MAC_MGMT_AUTH) |
365 BIT(SIR_MAC_MGMT_DEAUTH) |
366 BIT(SIR_MAC_MGMT_ACTION),
367 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700368 [NL80211_IFTYPE_ADHOC] = {
369 .tx = 0xffff,
370 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
371 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
372 BIT(SIR_MAC_MGMT_PROBE_REQ) |
373 BIT(SIR_MAC_MGMT_DISASSOC) |
374 BIT(SIR_MAC_MGMT_AUTH) |
375 BIT(SIR_MAC_MGMT_DEAUTH) |
376 BIT(SIR_MAC_MGMT_ACTION),
377 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700378 [NL80211_IFTYPE_P2P_CLIENT] = {
379 .tx = 0xffff,
380 .rx = BIT(SIR_MAC_MGMT_ACTION) |
381 BIT(SIR_MAC_MGMT_PROBE_REQ),
382 },
383 [NL80211_IFTYPE_P2P_GO] = {
384 /* This is also same as for SoftAP */
385 .tx = 0xffff,
386 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
387 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
388 BIT(SIR_MAC_MGMT_PROBE_REQ) |
389 BIT(SIR_MAC_MGMT_DISASSOC) |
390 BIT(SIR_MAC_MGMT_AUTH) |
391 BIT(SIR_MAC_MGMT_DEAUTH) |
392 BIT(SIR_MAC_MGMT_ACTION),
393 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700394};
395
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800396#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800397static const struct ieee80211_iface_limit
398wlan_hdd_iface_limit[] = {
399 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800400 /* max = 3 ; Our driver create two interfaces during driver init
401 * wlan0 and p2p0 interfaces. p2p0 is considered as station
402 * interface until a group is formed. In JB architecture, once the
403 * group is formed, interface type of p2p0 is changed to P2P GO or
404 * Client.
405 * When supplicant remove the group, it first issue a set interface
406 * cmd to change the mode back to Station. In JB this works fine as
407 * we advertize two station type interface during driver init.
408 * Some vendors create separate interface for P2P GO/Client,
409 * after group formation(Third one). But while group remove
410 * supplicant first tries to change the mode(3rd interface) to STATION
411 * But as we advertized only two sta type interfaces nl80211 was
412 * returning error for the third one which was leading to failure in
413 * delete interface. Ideally while removing the group, supplicant
414 * should not try to change the 3rd interface mode to Station type.
415 * Till we get a fix in wpa_supplicant, we advertize max STA
416 * interface type to 3
417 */
418 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800419 .types = BIT(NL80211_IFTYPE_STATION),
420 },
421 {
422 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700423 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800424 },
425 {
426 .max = 1,
427 .types = BIT(NL80211_IFTYPE_P2P_GO) |
428 BIT(NL80211_IFTYPE_P2P_CLIENT),
429 },
430};
431
432/* By default, only single channel concurrency is allowed */
433static struct ieee80211_iface_combination
434wlan_hdd_iface_combination = {
435 .limits = wlan_hdd_iface_limit,
436 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800437 /*
438 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
439 * and p2p0 interfaces during driver init
440 * Some vendors create separate interface for P2P operations.
441 * wlan0: STA interface
442 * p2p0: P2P Device interface, action frames goes
443 * through this interface.
444 * p2p-xx: P2P interface, After GO negotiation this interface is
445 * created for p2p operations(GO/CLIENT interface).
446 */
447 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800448 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
449 .beacon_int_infra_match = false,
450};
451#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800452
Jeff Johnson295189b2012-06-20 16:38:30 -0700453static struct cfg80211_ops wlan_hdd_cfg80211_ops;
454
455/* Data rate 100KBPS based on IE Index */
456struct index_data_rate_type
457{
458 v_U8_t beacon_rate_index;
459 v_U16_t supported_rate[4];
460};
461
462/* 11B, 11G Rate table include Basic rate and Extended rate
463 The IDX field is the rate index
464 The HI field is the rate when RSSI is strong or being ignored
465 (in this case we report actual rate)
466 The MID field is the rate when RSSI is moderate
467 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
468 The LO field is the rate when RSSI is low
469 (in this case we don't report rates, actual current rate used)
470 */
471static const struct
472{
473 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700474 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700475} supported_data_rate[] =
476{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700477/* IDX HI HM LM LO (RSSI-based index */
478 {2, { 10, 10, 10, 0}},
479 {4, { 20, 20, 10, 0}},
480 {11, { 55, 20, 10, 0}},
481 {12, { 60, 55, 20, 0}},
482 {18, { 90, 55, 20, 0}},
483 {22, {110, 55, 20, 0}},
484 {24, {120, 90, 60, 0}},
485 {36, {180, 120, 60, 0}},
486 {44, {220, 180, 60, 0}},
487 {48, {240, 180, 90, 0}},
488 {66, {330, 180, 90, 0}},
489 {72, {360, 240, 90, 0}},
490 {96, {480, 240, 120, 0}},
491 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700492};
493
494/* MCS Based rate table */
495static struct index_data_rate_type supported_mcs_rate[] =
496{
497/* MCS L20 L40 S20 S40 */
498 {0, {65, 135, 72, 150}},
499 {1, {130, 270, 144, 300}},
500 {2, {195, 405, 217, 450}},
501 {3, {260, 540, 289, 600}},
502 {4, {390, 810, 433, 900}},
503 {5, {520, 1080, 578, 1200}},
504 {6, {585, 1215, 650, 1350}},
505 {7, {650, 1350, 722, 1500}}
506};
507
Leo Chang6f8870f2013-03-26 18:11:36 -0700508#ifdef WLAN_FEATURE_11AC
509
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530510#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700511
512struct index_vht_data_rate_type
513{
514 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530515 v_U16_t supported_VHT80_rate[2];
516 v_U16_t supported_VHT40_rate[2];
517 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700518};
519
520typedef enum
521{
522 DATA_RATE_11AC_MAX_MCS_7,
523 DATA_RATE_11AC_MAX_MCS_8,
524 DATA_RATE_11AC_MAX_MCS_9,
525 DATA_RATE_11AC_MAX_MCS_NA
526} eDataRate11ACMaxMcs;
527
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530528/* SSID broadcast type */
529typedef enum eSSIDBcastType
530{
531 eBCAST_UNKNOWN = 0,
532 eBCAST_NORMAL = 1,
533 eBCAST_HIDDEN = 2,
534} tSSIDBcastType;
535
Leo Chang6f8870f2013-03-26 18:11:36 -0700536/* MCS Based VHT rate table */
537static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
538{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530539/* MCS L80 S80 L40 S40 L20 S40*/
540 {0, {293, 325}, {135, 150}, {65, 72}},
541 {1, {585, 650}, {270, 300}, {130, 144}},
542 {2, {878, 975}, {405, 450}, {195, 217}},
543 {3, {1170, 1300}, {540, 600}, {260, 289}},
544 {4, {1755, 1950}, {810, 900}, {390, 433}},
545 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
546 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
547 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
548 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
549 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700550};
551#endif /* WLAN_FEATURE_11AC */
552
c_hpothu79aab322014-07-14 21:11:01 +0530553/*array index points to MCS and array value points respective rssi*/
554static int rssiMcsTbl[][10] =
555{
556/*MCS 0 1 2 3 4 5 6 7 8 9*/
557 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
558 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
559 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
560};
561
Jeff Johnson295189b2012-06-20 16:38:30 -0700562extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530563#ifdef FEATURE_WLAN_SCAN_PNO
564static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
565#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700566
Leo Chang9056f462013-08-01 19:21:11 -0700567#ifdef WLAN_NL80211_TESTMODE
568enum wlan_hdd_tm_attr
569{
570 WLAN_HDD_TM_ATTR_INVALID = 0,
571 WLAN_HDD_TM_ATTR_CMD = 1,
572 WLAN_HDD_TM_ATTR_DATA = 2,
573 WLAN_HDD_TM_ATTR_TYPE = 3,
574 /* keep last */
575 WLAN_HDD_TM_ATTR_AFTER_LAST,
576 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
577};
578
579enum wlan_hdd_tm_cmd
580{
581 WLAN_HDD_TM_CMD_WLAN_HB = 1,
582};
583
584#define WLAN_HDD_TM_DATA_MAX_LEN 5000
585
586static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
587{
588 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
589 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
590 .len = WLAN_HDD_TM_DATA_MAX_LEN },
591};
592#endif /* WLAN_NL80211_TESTMODE */
593
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800594#ifdef FEATURE_WLAN_CH_AVOID
595/*
596 * FUNCTION: wlan_hdd_send_avoid_freq_event
597 * This is called when wlan driver needs to send vendor specific
598 * avoid frequency range event to userspace
599 */
600int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
601 tHddAvoidFreqList *pAvoidFreqList)
602{
603 struct sk_buff *vendor_event;
604
605 ENTER();
606
607 if (!pHddCtx)
608 {
609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
610 "%s: HDD context is null", __func__);
611 return -1;
612 }
613
614 if (!pAvoidFreqList)
615 {
616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
617 "%s: pAvoidFreqList is null", __func__);
618 return -1;
619 }
620
621 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530622#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
623 NULL,
624#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800625 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530626 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800627 GFP_KERNEL);
628 if (!vendor_event)
629 {
630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
631 "%s: cfg80211_vendor_event_alloc failed", __func__);
632 return -1;
633 }
634
635 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
636 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
637
638 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
639
640 EXIT();
641 return 0;
642}
643#endif /* FEATURE_WLAN_CH_AVOID */
644
Srinivas Dasari030bad32015-02-18 23:23:54 +0530645/*
646 * FUNCTION: __wlan_hdd_cfg80211_nan_request
647 * This is called when wlan driver needs to send vendor specific
648 * nan request event.
649 */
650static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
651 struct wireless_dev *wdev,
652 const void *data, int data_len)
653{
654 tNanRequestReq nan_req;
655 VOS_STATUS status;
656 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530657 struct net_device *dev = wdev->netdev;
658 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
659 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530660 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
661
662 if (0 == data_len)
663 {
664 hddLog(VOS_TRACE_LEVEL_ERROR,
665 FL("NAN - Invalid Request, length = 0"));
666 return ret_val;
667 }
668
669 if (NULL == data)
670 {
671 hddLog(VOS_TRACE_LEVEL_ERROR,
672 FL("NAN - Invalid Request, data is NULL"));
673 return ret_val;
674 }
675
676 status = wlan_hdd_validate_context(pHddCtx);
677 if (0 != status)
678 {
679 hddLog(VOS_TRACE_LEVEL_ERROR,
680 FL("HDD context is not valid"));
681 return -EINVAL;
682 }
683
684 hddLog(LOG1, FL("Received NAN command"));
685 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
686 (tANI_U8 *)data, data_len);
687
688 /* check the NAN Capability */
689 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
690 {
691 hddLog(VOS_TRACE_LEVEL_ERROR,
692 FL("NAN is not supported by Firmware"));
693 return -EINVAL;
694 }
695
696 nan_req.request_data_len = data_len;
697 nan_req.request_data = data;
698
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530699 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530700 if (VOS_STATUS_SUCCESS == status)
701 {
702 ret_val = 0;
703 }
704 return ret_val;
705}
706
707/*
708 * FUNCTION: wlan_hdd_cfg80211_nan_request
709 * Wrapper to protect the nan vendor command from ssr
710 */
711static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
712 struct wireless_dev *wdev,
713 const void *data, int data_len)
714{
715 int ret;
716
717 vos_ssr_protect(__func__);
718 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
719 vos_ssr_unprotect(__func__);
720
721 return ret;
722}
723
724/*
725 * FUNCTION: wlan_hdd_cfg80211_nan_callback
726 * This is a callback function and it gets called
727 * when we need to report nan response event to
728 * upper layers.
729 */
730static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
731{
732 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
733 struct sk_buff *vendor_event;
734 int status;
735 tSirNanEvent *data;
736
737 ENTER();
738 if (NULL == msg)
739 {
740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
741 FL(" msg received here is null"));
742 return;
743 }
744 data = msg;
745
746 status = wlan_hdd_validate_context(pHddCtx);
747
748 if (0 != status)
749 {
750 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
751 FL("HDD context is not valid"));
752 return;
753 }
754
755 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530756#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
757 NULL,
758#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530759 data->event_data_len +
760 NLMSG_HDRLEN,
761 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
762 GFP_KERNEL);
763
764 if (!vendor_event)
765 {
766 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
767 FL("cfg80211_vendor_event_alloc failed"));
768 return;
769 }
770 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
771 data->event_data_len, data->event_data))
772 {
773 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
774 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
775 kfree_skb(vendor_event);
776 return;
777 }
778 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
779 EXIT();
780}
781
782/*
783 * FUNCTION: wlan_hdd_cfg80211_nan_init
784 * This function is called to register the callback to sme layer
785 */
786inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
787{
788 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
789}
790
791
Sunil Duttc69bccb2014-05-26 21:30:20 +0530792#ifdef WLAN_FEATURE_LINK_LAYER_STATS
793
794static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
795 struct sk_buff *vendor_event)
796{
797 if (nla_put_u8(vendor_event,
798 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
799 stats->rate.preamble) ||
800 nla_put_u8(vendor_event,
801 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
802 stats->rate.nss) ||
803 nla_put_u8(vendor_event,
804 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
805 stats->rate.bw) ||
806 nla_put_u8(vendor_event,
807 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
808 stats->rate.rateMcsIdx) ||
809 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
810 stats->rate.bitrate ) ||
811 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
812 stats->txMpdu ) ||
813 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
814 stats->rxMpdu ) ||
815 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
816 stats->mpduLost ) ||
817 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
818 stats->retries) ||
819 nla_put_u32(vendor_event,
820 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
821 stats->retriesShort ) ||
822 nla_put_u32(vendor_event,
823 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
824 stats->retriesLong))
825 {
826 hddLog(VOS_TRACE_LEVEL_ERROR,
827 FL("QCA_WLAN_VENDOR_ATTR put fail"));
828 return FALSE;
829 }
830 return TRUE;
831}
832
833static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
834 struct sk_buff *vendor_event)
835{
836 u32 i = 0;
837 struct nlattr *rateInfo;
838 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
839 stats->type) ||
840 nla_put(vendor_event,
841 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
842 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
843 nla_put_u32(vendor_event,
844 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
845 stats->capabilities) ||
846 nla_put_u32(vendor_event,
847 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
848 stats->numRate))
849 {
850 hddLog(VOS_TRACE_LEVEL_ERROR,
851 FL("QCA_WLAN_VENDOR_ATTR put fail"));
852 goto error;
853 }
854
855 rateInfo = nla_nest_start(vendor_event,
856 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530857 if(!rateInfo)
858 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530859 for (i = 0; i < stats->numRate; i++)
860 {
861 struct nlattr *rates;
862 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
863 stats->rateStats +
864 (i * sizeof(tSirWifiRateStat)));
865 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530866 if(!rates)
867 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530868
869 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
870 {
871 hddLog(VOS_TRACE_LEVEL_ERROR,
872 FL("QCA_WLAN_VENDOR_ATTR put fail"));
873 return FALSE;
874 }
875 nla_nest_end(vendor_event, rates);
876 }
877 nla_nest_end(vendor_event, rateInfo);
878
879 return TRUE;
880error:
881 return FALSE;
882}
883
884static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
885 struct sk_buff *vendor_event)
886{
887 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
888 stats->ac ) ||
889 nla_put_u32(vendor_event,
890 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
891 stats->txMpdu ) ||
892 nla_put_u32(vendor_event,
893 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
894 stats->rxMpdu ) ||
895 nla_put_u32(vendor_event,
896 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
897 stats->txMcast ) ||
898 nla_put_u32(vendor_event,
899 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
900 stats->rxMcast ) ||
901 nla_put_u32(vendor_event,
902 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
903 stats->rxAmpdu ) ||
904 nla_put_u32(vendor_event,
905 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
906 stats->txAmpdu ) ||
907 nla_put_u32(vendor_event,
908 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
909 stats->mpduLost )||
910 nla_put_u32(vendor_event,
911 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
912 stats->retries ) ||
913 nla_put_u32(vendor_event,
914 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
915 stats->retriesShort ) ||
916 nla_put_u32(vendor_event,
917 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
918 stats->retriesLong ) ||
919 nla_put_u32(vendor_event,
920 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
921 stats->contentionTimeMin ) ||
922 nla_put_u32(vendor_event,
923 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
924 stats->contentionTimeMax ) ||
925 nla_put_u32(vendor_event,
926 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
927 stats->contentionTimeAvg ) ||
928 nla_put_u32(vendor_event,
929 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
930 stats->contentionNumSamples ))
931 {
932 hddLog(VOS_TRACE_LEVEL_ERROR,
933 FL("QCA_WLAN_VENDOR_ATTR put fail") );
934 return FALSE;
935 }
936 return TRUE;
937}
938
939static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
940 struct sk_buff *vendor_event)
941{
Dino Myclec8f3f332014-07-21 16:48:27 +0530942 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530943 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
944 nla_put(vendor_event,
945 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
946 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
947 nla_put_u32(vendor_event,
948 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
949 stats->state ) ||
950 nla_put_u32(vendor_event,
951 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
952 stats->roaming ) ||
953 nla_put_u32(vendor_event,
954 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
955 stats->capabilities ) ||
956 nla_put(vendor_event,
957 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
958 strlen(stats->ssid), stats->ssid) ||
959 nla_put(vendor_event,
960 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
961 WNI_CFG_BSSID_LEN, stats->bssid) ||
962 nla_put(vendor_event,
963 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
964 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
965 nla_put(vendor_event,
966 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
967 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
968 )
969 {
970 hddLog(VOS_TRACE_LEVEL_ERROR,
971 FL("QCA_WLAN_VENDOR_ATTR put fail") );
972 return FALSE;
973 }
974 return TRUE;
975}
976
Dino Mycle3b9536d2014-07-09 22:05:24 +0530977static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
978 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530979 struct sk_buff *vendor_event)
980{
981 int i = 0;
982 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530983 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
984 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530985 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530986
Sunil Duttc69bccb2014-05-26 21:30:20 +0530987 if (FALSE == put_wifi_interface_info(
988 &pWifiIfaceStat->info,
989 vendor_event))
990 {
991 hddLog(VOS_TRACE_LEVEL_ERROR,
992 FL("QCA_WLAN_VENDOR_ATTR put fail") );
993 return FALSE;
994
995 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530996 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
997 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
998 if (NULL == pWifiIfaceStatTL)
999 {
1000 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
1001 return FALSE;
1002 }
1003
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301004 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
1005 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1006 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1007 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1008
1009 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1010 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1011 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1012 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301013
1014 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1015 {
1016 if (VOS_STATUS_SUCCESS ==
1017 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1018 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1019 {
1020 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1021 * obtained from TL structure
1022 */
1023
1024 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1025 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301026 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1027
Srinivas Dasari98947432014-11-07 19:41:24 +05301028 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1029 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1030 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1031 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1032 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1033 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1034 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1035 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301036
Srinivas Dasari98947432014-11-07 19:41:24 +05301037 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1038 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1039 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1040 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1041 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1042 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1043 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1044 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301045
Srinivas Dasari98947432014-11-07 19:41:24 +05301046 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1047 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1048 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1049 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1050 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1051 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1052 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1053 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301054 }
1055 else
1056 {
1057 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1058 }
1059
Dino Mycle3b9536d2014-07-09 22:05:24 +05301060 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1061 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1062 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1063 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1064 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1065 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1066 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1067 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1068 }
1069 else
1070 {
1071 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1072 }
1073
1074
Sunil Duttc69bccb2014-05-26 21:30:20 +05301075
1076 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301077 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1078 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1079 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301080 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1081 pWifiIfaceStat->beaconRx) ||
1082 nla_put_u32(vendor_event,
1083 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1084 pWifiIfaceStat->mgmtRx) ||
1085 nla_put_u32(vendor_event,
1086 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1087 pWifiIfaceStat->mgmtActionRx) ||
1088 nla_put_u32(vendor_event,
1089 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1090 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301091 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301092 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1093 pWifiIfaceStat->rssiMgmt) ||
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_DATA,
1096 pWifiIfaceStat->rssiData) ||
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_ACK,
1099 pWifiIfaceStat->rssiAck))
1100 {
1101 hddLog(VOS_TRACE_LEVEL_ERROR,
1102 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301103 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301104 return FALSE;
1105 }
1106
1107 wmmInfo = nla_nest_start(vendor_event,
1108 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301109 if(!wmmInfo)
1110 {
1111 vos_mem_free(pWifiIfaceStatTL);
1112 return FALSE;
1113 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301114 for (i = 0; i < WIFI_AC_MAX; i++)
1115 {
1116 struct nlattr *wmmStats;
1117 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301118 if(!wmmStats)
1119 {
1120 vos_mem_free(pWifiIfaceStatTL);
1121 return FALSE;
1122 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301123 if (FALSE == put_wifi_wmm_ac_stat(
1124 &pWifiIfaceStat->AccessclassStats[i],
1125 vendor_event))
1126 {
1127 hddLog(VOS_TRACE_LEVEL_ERROR,
1128 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301129 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301130 return FALSE;
1131 }
1132
1133 nla_nest_end(vendor_event, wmmStats);
1134 }
1135 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301136 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301137 return TRUE;
1138}
1139
1140static tSirWifiInterfaceMode
1141 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1142{
1143 switch (deviceMode)
1144 {
1145 case WLAN_HDD_INFRA_STATION:
1146 return WIFI_INTERFACE_STA;
1147 case WLAN_HDD_SOFTAP:
1148 return WIFI_INTERFACE_SOFTAP;
1149 case WLAN_HDD_P2P_CLIENT:
1150 return WIFI_INTERFACE_P2P_CLIENT;
1151 case WLAN_HDD_P2P_GO:
1152 return WIFI_INTERFACE_P2P_GO;
1153 case WLAN_HDD_IBSS:
1154 return WIFI_INTERFACE_IBSS;
1155 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301156 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301157 }
1158}
1159
1160static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1161 tpSirWifiInterfaceInfo pInfo)
1162{
1163 v_U8_t *staMac = NULL;
1164 hdd_station_ctx_t *pHddStaCtx;
1165 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1166 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1167
1168 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1169
1170 vos_mem_copy(pInfo->macAddr,
1171 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1172
1173 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1174 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1175 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1176 {
1177 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1178 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1179 {
1180 pInfo->state = WIFI_DISCONNECTED;
1181 }
1182 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1183 {
1184 hddLog(VOS_TRACE_LEVEL_ERROR,
1185 "%s: Session ID %d, Connection is in progress", __func__,
1186 pAdapter->sessionId);
1187 pInfo->state = WIFI_ASSOCIATING;
1188 }
1189 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1190 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1191 {
1192 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1193 hddLog(VOS_TRACE_LEVEL_ERROR,
1194 "%s: client " MAC_ADDRESS_STR
1195 " is in the middle of WPS/EAPOL exchange.", __func__,
1196 MAC_ADDR_ARRAY(staMac));
1197 pInfo->state = WIFI_AUTHENTICATING;
1198 }
1199 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1200 {
1201 pInfo->state = WIFI_ASSOCIATED;
1202 vos_mem_copy(pInfo->bssid,
1203 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1204 vos_mem_copy(pInfo->ssid,
1205 pHddStaCtx->conn_info.SSID.SSID.ssId,
1206 pHddStaCtx->conn_info.SSID.SSID.length);
1207 //NULL Terminate the string.
1208 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1209 }
1210 }
1211 vos_mem_copy(pInfo->countryStr,
1212 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1213
1214 vos_mem_copy(pInfo->apCountryStr,
1215 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1216
1217 return TRUE;
1218}
1219
1220/*
1221 * hdd_link_layer_process_peer_stats () - This function is called after
1222 * receiving Link Layer Peer statistics from FW.This function converts
1223 * the firmware data to the NL data and sends the same to the kernel/upper
1224 * layers.
1225 */
1226static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1227 v_VOID_t *pData)
1228{
1229 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1230 tpSirWifiRateStat pWifiRateStat;
1231 tpSirWifiPeerStat pWifiPeerStat;
1232 tpSirWifiPeerInfo pWifiPeerInfo;
1233 struct nlattr *peerInfo;
1234 struct sk_buff *vendor_event;
1235 int status, i;
1236
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301237 ENTER();
1238
Sunil Duttc69bccb2014-05-26 21:30:20 +05301239 status = wlan_hdd_validate_context(pHddCtx);
1240 if (0 != status)
1241 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301242 return;
1243 }
1244
1245 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1246
1247 hddLog(VOS_TRACE_LEVEL_INFO,
1248 "LL_STATS_PEER_ALL : numPeers %u",
1249 pWifiPeerStat->numPeers);
1250 {
1251 for (i = 0; i < pWifiPeerStat->numPeers; i++)
1252 {
1253 pWifiPeerInfo = (tpSirWifiPeerInfo)
1254 ((uint8 *)pWifiPeerStat->peerInfo +
1255 ( i * sizeof(tSirWifiPeerInfo)));
1256
Dasari Srinivas1be0c4e2014-10-19 13:03:41 +05301257 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) {
1258 pWifiPeerInfo->type = WIFI_PEER_AP;
1259 }
1260 if (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) {
1261 pWifiPeerInfo->type = WIFI_PEER_P2P_GO;
1262 }
1263
Sunil Duttc69bccb2014-05-26 21:30:20 +05301264 hddLog(VOS_TRACE_LEVEL_INFO,
1265 " %d) LL_STATS Channel Stats "
1266 " Peer Type %u "
1267 " peerMacAddress %pM "
1268 " capabilities 0x%x "
1269 " numRate %u ",
1270 i,
1271 pWifiPeerInfo->type,
1272 pWifiPeerInfo->peerMacAddress,
1273 pWifiPeerInfo->capabilities,
1274 pWifiPeerInfo->numRate);
1275 {
1276 int j;
1277 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1278 {
1279 pWifiRateStat = (tpSirWifiRateStat)
1280 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1281 ( j * sizeof(tSirWifiRateStat)));
1282
1283 hddLog(VOS_TRACE_LEVEL_INFO,
1284 " peer Rate Stats "
1285 " preamble %u "
1286 " nss %u "
1287 " bw %u "
1288 " rateMcsIdx %u "
1289 " reserved %u "
1290 " bitrate %u "
1291 " txMpdu %u "
1292 " rxMpdu %u "
1293 " mpduLost %u "
1294 " retries %u "
1295 " retriesShort %u "
1296 " retriesLong %u",
1297 pWifiRateStat->rate.preamble,
1298 pWifiRateStat->rate.nss,
1299 pWifiRateStat->rate.bw,
1300 pWifiRateStat->rate.rateMcsIdx,
1301 pWifiRateStat->rate.reserved,
1302 pWifiRateStat->rate.bitrate,
1303 pWifiRateStat->txMpdu,
1304 pWifiRateStat->rxMpdu,
1305 pWifiRateStat->mpduLost,
1306 pWifiRateStat->retries,
1307 pWifiRateStat->retriesShort,
1308 pWifiRateStat->retriesLong);
1309 }
1310 }
1311 }
1312 }
1313
1314 /*
1315 * Allocate a size of 4096 for the peer stats comprising
1316 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1317 * sizeof (tSirWifiRateStat).Each field is put with an
1318 * NL attribute.The size of 4096 is considered assuming
1319 * that number of rates shall not exceed beyond 50 with
1320 * the sizeof (tSirWifiRateStat) being 32.
1321 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301322 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1323 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301324 if (!vendor_event)
1325 {
1326 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301327 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301328 __func__);
1329 return;
1330 }
1331 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301332 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1333 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1334 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301335 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1336 pWifiPeerStat->numPeers))
1337 {
1338 hddLog(VOS_TRACE_LEVEL_ERROR,
1339 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1340 kfree_skb(vendor_event);
1341 return;
1342 }
1343
1344 peerInfo = nla_nest_start(vendor_event,
1345 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301346 if(!peerInfo)
1347 {
1348 hddLog(VOS_TRACE_LEVEL_ERROR,
1349 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1350 __func__);
1351 kfree_skb(vendor_event);
1352 return;
1353 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301354
1355 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1356 pWifiPeerStat->peerInfo);
1357
1358 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1359 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301360 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301361 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301362
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301363 if(!peers)
1364 {
1365 hddLog(VOS_TRACE_LEVEL_ERROR,
1366 "%s: peer stats put fail",
1367 __func__);
1368 kfree_skb(vendor_event);
1369 return;
1370 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301371 if (FALSE == put_wifi_peer_info(
1372 pWifiPeerInfo, vendor_event))
1373 {
1374 hddLog(VOS_TRACE_LEVEL_ERROR,
1375 "%s: put_wifi_peer_info put fail", __func__);
1376 kfree_skb(vendor_event);
1377 return;
1378 }
1379
1380 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1381 pWifiPeerStat->peerInfo +
1382 (i * sizeof(tSirWifiPeerInfo)) +
1383 (numRate * sizeof (tSirWifiRateStat)));
1384 nla_nest_end(vendor_event, peers);
1385 }
1386 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301387 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301388 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301389}
1390
1391/*
1392 * hdd_link_layer_process_iface_stats () - This function is called after
1393 * receiving Link Layer Interface statistics from FW.This function converts
1394 * the firmware data to the NL data and sends the same to the kernel/upper
1395 * layers.
1396 */
1397static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1398 v_VOID_t *pData)
1399{
1400 tpSirWifiIfaceStat pWifiIfaceStat;
1401 struct sk_buff *vendor_event;
1402 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1403 int status;
1404
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301405 ENTER();
1406
Sunil Duttc69bccb2014-05-26 21:30:20 +05301407 status = wlan_hdd_validate_context(pHddCtx);
1408 if (0 != status)
1409 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301410 return;
1411 }
1412 /*
1413 * Allocate a size of 4096 for the interface stats comprising
1414 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1415 * assuming that all these fit with in the limit.Please take
1416 * a call on the limit based on the data requirements on
1417 * interface statistics.
1418 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301419 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1420 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301421 if (!vendor_event)
1422 {
1423 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301424 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301425 return;
1426 }
1427
1428 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1429
Dino Mycle3b9536d2014-07-09 22:05:24 +05301430
1431 if (FALSE == hdd_get_interface_info( pAdapter,
1432 &pWifiIfaceStat->info))
1433 {
1434 hddLog(VOS_TRACE_LEVEL_ERROR,
1435 FL("hdd_get_interface_info get fail") );
1436 kfree_skb(vendor_event);
1437 return;
1438 }
1439
1440 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1441 vendor_event))
1442 {
1443 hddLog(VOS_TRACE_LEVEL_ERROR,
1444 FL("put_wifi_iface_stats fail") );
1445 kfree_skb(vendor_event);
1446 return;
1447 }
1448
Sunil Duttc69bccb2014-05-26 21:30:20 +05301449 hddLog(VOS_TRACE_LEVEL_INFO,
1450 "WMI_LINK_STATS_IFACE Data");
1451
1452 hddLog(VOS_TRACE_LEVEL_INFO,
1453 "LL_STATS_IFACE: "
1454 " Mode %u "
1455 " MAC %pM "
1456 " State %u "
1457 " Roaming %u "
1458 " capabilities 0x%x "
1459 " SSID %s "
1460 " BSSID %pM",
1461 pWifiIfaceStat->info.mode,
1462 pWifiIfaceStat->info.macAddr,
1463 pWifiIfaceStat->info.state,
1464 pWifiIfaceStat->info.roaming,
1465 pWifiIfaceStat->info.capabilities,
1466 pWifiIfaceStat->info.ssid,
1467 pWifiIfaceStat->info.bssid);
1468
1469 hddLog(VOS_TRACE_LEVEL_INFO,
1470 " AP country str: %c%c%c",
1471 pWifiIfaceStat->info.apCountryStr[0],
1472 pWifiIfaceStat->info.apCountryStr[1],
1473 pWifiIfaceStat->info.apCountryStr[2]);
1474
1475
1476 hddLog(VOS_TRACE_LEVEL_INFO,
1477 " Country Str Association: %c%c%c",
1478 pWifiIfaceStat->info.countryStr[0],
1479 pWifiIfaceStat->info.countryStr[1],
1480 pWifiIfaceStat->info.countryStr[2]);
1481
1482 hddLog(VOS_TRACE_LEVEL_INFO,
1483 " beaconRx %u "
1484 " mgmtRx %u "
1485 " mgmtActionRx %u "
1486 " mgmtActionTx %u "
Dino Mycle3b9536d2014-07-09 22:05:24 +05301487 " rssiMgmt %d "
1488 " rssiData %d "
1489 " rssiAck %d",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301490 pWifiIfaceStat->beaconRx,
1491 pWifiIfaceStat->mgmtRx,
1492 pWifiIfaceStat->mgmtActionRx,
1493 pWifiIfaceStat->mgmtActionTx,
1494 pWifiIfaceStat->rssiMgmt,
1495 pWifiIfaceStat->rssiData,
1496 pWifiIfaceStat->rssiAck );
1497
1498
1499 {
1500 int i;
1501 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1502 {
1503 hddLog(VOS_TRACE_LEVEL_INFO,
1504
1505 " %d) LL_STATS IFACE: "
1506 " ac: %u txMpdu: %u "
1507 " rxMpdu: %u txMcast: %u "
1508 " rxMcast: %u rxAmpdu: %u "
1509 " txAmpdu: %u mpduLost: %u "
1510 " retries: %u retriesShort: %u "
1511 " retriesLong: %u contentionTimeMin: %u "
1512 " contentionTimeMax: %u contentionTimeAvg: %u "
1513 " contentionNumSamples: %u",
1514 i,
1515 pWifiIfaceStat->AccessclassStats[i].ac,
1516 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1517 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1518 pWifiIfaceStat->AccessclassStats[i].txMcast,
1519 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1520 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1521 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1522 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1523 pWifiIfaceStat->AccessclassStats[i].retries,
1524 pWifiIfaceStat->
1525 AccessclassStats[i].retriesShort,
1526 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1527 pWifiIfaceStat->
1528 AccessclassStats[i].contentionTimeMin,
1529 pWifiIfaceStat->
1530 AccessclassStats[i].contentionTimeMax,
1531 pWifiIfaceStat->
1532 AccessclassStats[i].contentionTimeAvg,
1533 pWifiIfaceStat->
1534 AccessclassStats[i].contentionNumSamples);
1535
1536 }
1537 }
1538
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301539 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301540
1541 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301542}
1543
1544/*
1545 * hdd_link_layer_process_radio_stats () - This function is called after
1546 * receiving Link Layer Radio statistics from FW.This function converts
1547 * the firmware data to the NL data and sends the same to the kernel/upper
1548 * layers.
1549 */
1550static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1551 v_VOID_t *pData)
1552{
1553 int status, i;
1554 tpSirWifiRadioStat pWifiRadioStat;
1555 tpSirWifiChannelStats pWifiChannelStats;
1556 struct sk_buff *vendor_event;
1557 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1558 struct nlattr *chList;
1559
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301560 ENTER();
1561
Sunil Duttc69bccb2014-05-26 21:30:20 +05301562 status = wlan_hdd_validate_context(pHddCtx);
1563 if (0 != status)
1564 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301565 return;
1566 }
1567 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1568
1569 hddLog(VOS_TRACE_LEVEL_INFO,
1570 "LL_STATS_RADIO"
1571 " radio is %d onTime is %u "
1572 " txTime is %u rxTime is %u "
1573 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301574 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301575 " onTimePnoScan is %u onTimeHs20 is %u "
1576 " numChannels is %u",
1577 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1578 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1579 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301580 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301581 pWifiRadioStat->onTimeRoamScan,
1582 pWifiRadioStat->onTimePnoScan,
1583 pWifiRadioStat->onTimeHs20,
1584 pWifiRadioStat->numChannels);
1585 /*
1586 * Allocate a size of 4096 for the Radio stats comprising
1587 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1588 * (tSirWifiChannelStats).Each channel data is put with an
1589 * NL attribute.The size of 4096 is considered assuming that
1590 * number of channels shall not exceed beyond 60 with the
1591 * sizeof (tSirWifiChannelStats) being 24 bytes.
1592 */
1593
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301594 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1595 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301596 if (!vendor_event)
1597 {
1598 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301599 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301600 return;
1601 }
1602
1603 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301604 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1605 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1606 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301607 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1608 pWifiRadioStat->radio) ||
1609 nla_put_u32(vendor_event,
1610 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1611 pWifiRadioStat->onTime) ||
1612 nla_put_u32(vendor_event,
1613 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1614 pWifiRadioStat->txTime) ||
1615 nla_put_u32(vendor_event,
1616 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1617 pWifiRadioStat->rxTime) ||
1618 nla_put_u32(vendor_event,
1619 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1620 pWifiRadioStat->onTimeScan) ||
1621 nla_put_u32(vendor_event,
1622 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1623 pWifiRadioStat->onTimeNbd) ||
1624 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301625 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1626 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301627 nla_put_u32(vendor_event,
1628 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1629 pWifiRadioStat->onTimeRoamScan) ||
1630 nla_put_u32(vendor_event,
1631 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1632 pWifiRadioStat->onTimePnoScan) ||
1633 nla_put_u32(vendor_event,
1634 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1635 pWifiRadioStat->onTimeHs20) ||
1636 nla_put_u32(vendor_event,
1637 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1638 pWifiRadioStat->numChannels))
1639 {
1640 hddLog(VOS_TRACE_LEVEL_ERROR,
1641 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1642 kfree_skb(vendor_event);
1643 return ;
1644 }
1645
1646 chList = nla_nest_start(vendor_event,
1647 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301648 if(!chList)
1649 {
1650 hddLog(VOS_TRACE_LEVEL_ERROR,
1651 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1652 __func__);
1653 kfree_skb(vendor_event);
1654 return;
1655 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301656 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1657 {
1658 struct nlattr *chInfo;
1659
1660 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1661 pWifiRadioStat->channels +
1662 (i * sizeof(tSirWifiChannelStats)));
1663
1664 hddLog(VOS_TRACE_LEVEL_INFO,
1665 " %d) Channel Info"
1666 " width is %u "
1667 " CenterFreq %u "
1668 " CenterFreq0 %u "
1669 " CenterFreq1 %u "
1670 " onTime %u "
1671 " ccaBusyTime %u",
1672 i,
1673 pWifiChannelStats->channel.width,
1674 pWifiChannelStats->channel.centerFreq,
1675 pWifiChannelStats->channel.centerFreq0,
1676 pWifiChannelStats->channel.centerFreq1,
1677 pWifiChannelStats->onTime,
1678 pWifiChannelStats->ccaBusyTime);
1679
1680
1681 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301682 if(!chInfo)
1683 {
1684 hddLog(VOS_TRACE_LEVEL_ERROR,
1685 "%s: failed to put chInfo",
1686 __func__);
1687 kfree_skb(vendor_event);
1688 return;
1689 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301690
1691 if (nla_put_u32(vendor_event,
1692 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1693 pWifiChannelStats->channel.width) ||
1694 nla_put_u32(vendor_event,
1695 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1696 pWifiChannelStats->channel.centerFreq) ||
1697 nla_put_u32(vendor_event,
1698 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1699 pWifiChannelStats->channel.centerFreq0) ||
1700 nla_put_u32(vendor_event,
1701 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1702 pWifiChannelStats->channel.centerFreq1) ||
1703 nla_put_u32(vendor_event,
1704 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1705 pWifiChannelStats->onTime) ||
1706 nla_put_u32(vendor_event,
1707 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1708 pWifiChannelStats->ccaBusyTime))
1709 {
1710 hddLog(VOS_TRACE_LEVEL_ERROR,
1711 FL("cfg80211_vendor_event_alloc failed") );
1712 kfree_skb(vendor_event);
1713 return ;
1714 }
1715 nla_nest_end(vendor_event, chInfo);
1716 }
1717 nla_nest_end(vendor_event, chList);
1718
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301719 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301720
1721 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301722 return;
1723}
1724
1725/*
1726 * hdd_link_layer_stats_ind_callback () - This function is called after
1727 * receiving Link Layer indications from FW.This callback converts the firmware
1728 * data to the NL data and send the same to the kernel/upper layers.
1729 */
1730static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1731 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301732 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301733{
Dino Mycled3d50022014-07-07 12:58:25 +05301734 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1735 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301736 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301737 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301738 int status;
1739
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301740 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301741
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301742 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301743 if (0 != status)
1744 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301745 return;
1746 }
1747
Dino Mycled3d50022014-07-07 12:58:25 +05301748 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1749 if (NULL == pAdapter)
1750 {
1751 hddLog(VOS_TRACE_LEVEL_ERROR,
1752 FL(" MAC address %pM does not exist with host"),
1753 macAddr);
1754 return;
1755 }
1756
Sunil Duttc69bccb2014-05-26 21:30:20 +05301757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301758 "%s: Interface: %s LLStats indType: %d", __func__,
1759 pAdapter->dev->name, indType);
1760
Sunil Duttc69bccb2014-05-26 21:30:20 +05301761 switch (indType)
1762 {
1763 case SIR_HAL_LL_STATS_RESULTS_RSP:
1764 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301765 hddLog(VOS_TRACE_LEVEL_INFO,
1766 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1767 hddLog(VOS_TRACE_LEVEL_INFO,
1768 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1769 linkLayerStatsResults->paramId);
1770 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301771 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1772 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301773 hddLog(VOS_TRACE_LEVEL_INFO,
1774 "LL_STATS RESULTS RESPONSE respId = %u",
1775 linkLayerStatsResults->respId);
1776 hddLog(VOS_TRACE_LEVEL_INFO,
1777 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1778 linkLayerStatsResults->moreResultToFollow);
1779 hddLog(VOS_TRACE_LEVEL_INFO,
1780 "LL_STATS RESULTS RESPONSE result = %p",
1781 linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301782 spin_lock(&hdd_context_lock);
1783 context = &pHddCtx->ll_stats_context;
1784 /* validate response received from target */
1785 if ((context->request_id != linkLayerStatsResults->respId) ||
1786 !(context->request_bitmap & linkLayerStatsResults->paramId))
1787 {
1788 spin_unlock(&hdd_context_lock);
1789 hddLog(LOGE,
1790 FL("Error : Request id %d response id %d request bitmap 0x%x"
1791 "response bitmap 0x%x"),
1792 context->request_id, linkLayerStatsResults->respId,
1793 context->request_bitmap, linkLayerStatsResults->paramId);
1794 return;
1795 }
1796 spin_unlock(&hdd_context_lock);
1797
Sunil Duttc69bccb2014-05-26 21:30:20 +05301798 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1799 {
1800 hdd_link_layer_process_radio_stats(pAdapter,
1801 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301802 spin_lock(&hdd_context_lock);
1803 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1804 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301805 }
1806 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1807 {
1808 hdd_link_layer_process_iface_stats(pAdapter,
1809 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301810 spin_lock(&hdd_context_lock);
1811 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1812 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301813 }
1814 else if ( linkLayerStatsResults->paramId &
1815 WMI_LINK_STATS_ALL_PEER )
1816 {
1817 hdd_link_layer_process_peer_stats(pAdapter,
1818 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301819 spin_lock(&hdd_context_lock);
1820 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1821 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301822 } /* WMI_LINK_STATS_ALL_PEER */
1823 else
1824 {
1825 hddLog(VOS_TRACE_LEVEL_ERROR,
1826 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1827 }
1828
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301829 spin_lock(&hdd_context_lock);
1830 /* complete response event if all requests are completed */
1831 if (0 == context->request_bitmap)
1832 complete(&context->response_event);
1833 spin_unlock(&hdd_context_lock);
1834
Sunil Duttc69bccb2014-05-26 21:30:20 +05301835 break;
1836 }
1837 default:
1838 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1839 break;
1840 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301841
1842 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301843 return;
1844}
1845
1846const struct
1847nla_policy
1848qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1849{
1850 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1851 { .type = NLA_U32 },
1852 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1853 { .type = NLA_U32 },
1854};
1855
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301856static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1857 struct wireless_dev *wdev,
1858 const void *data,
1859 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301860{
1861 int status;
1862 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301863 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301864 struct net_device *dev = wdev->netdev;
1865 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1866 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1867
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301868 ENTER();
1869
Sunil Duttc69bccb2014-05-26 21:30:20 +05301870 status = wlan_hdd_validate_context(pHddCtx);
1871 if (0 != status)
1872 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301873 return -EINVAL;
1874 }
1875
1876 if (NULL == pAdapter)
1877 {
1878 hddLog(VOS_TRACE_LEVEL_ERROR,
1879 FL("HDD adapter is Null"));
1880 return -ENODEV;
1881 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301882 /* check the LLStats Capability */
1883 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1884 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1885 {
1886 hddLog(VOS_TRACE_LEVEL_ERROR,
1887 FL("Link Layer Statistics not supported by Firmware"));
1888 return -EINVAL;
1889 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301890
1891 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1892 (struct nlattr *)data,
1893 data_len, qca_wlan_vendor_ll_set_policy))
1894 {
1895 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1896 return -EINVAL;
1897 }
1898 if (!tb_vendor
1899 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1900 {
1901 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1902 return -EINVAL;
1903 }
1904 if (!tb_vendor[
1905 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1906 {
1907 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1908 return -EINVAL;
1909 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301910 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301911 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301912
Dino Mycledf0a5d92014-07-04 09:41:55 +05301913 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301914 nla_get_u32(
1915 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1916
Dino Mycledf0a5d92014-07-04 09:41:55 +05301917 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301918 nla_get_u32(
1919 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1920
Dino Mycled3d50022014-07-07 12:58:25 +05301921 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1922 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301923
1924
1925 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301926 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301927 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301928 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301929 hddLog(VOS_TRACE_LEVEL_INFO,
1930 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301931 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301932 hddLog(VOS_TRACE_LEVEL_INFO,
1933 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301934 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301935
1936 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1937 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301938 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301939 {
1940 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1941 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301942 return -EINVAL;
1943
1944 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301945
Sunil Duttc69bccb2014-05-26 21:30:20 +05301946 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301947 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301948 {
1949 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1950 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301951 return -EINVAL;
1952 }
1953
1954 pAdapter->isLinkLayerStatsSet = 1;
1955
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301956 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301957 return 0;
1958}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301959static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1960 struct wireless_dev *wdev,
1961 const void *data,
1962 int data_len)
1963{
1964 int ret = 0;
1965
1966 vos_ssr_protect(__func__);
1967 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1968 vos_ssr_unprotect(__func__);
1969
1970 return ret;
1971}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301972
1973const struct
1974nla_policy
1975qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1976{
1977 /* Unsigned 32bit value provided by the caller issuing the GET stats
1978 * command. When reporting
1979 * the stats results, the driver uses the same value to indicate
1980 * which GET request the results
1981 * correspond to.
1982 */
1983 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1984
1985 /* Unsigned 32bit value . bit mask to identify what statistics are
1986 requested for retrieval */
1987 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1988};
1989
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301990static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1991 struct wireless_dev *wdev,
1992 const void *data,
1993 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301994{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301995 unsigned long rc;
1996 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301997 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1998 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301999 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302000 struct net_device *dev = wdev->netdev;
2001 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302002 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302003 int status;
2004
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302005 ENTER();
2006
Sunil Duttc69bccb2014-05-26 21:30:20 +05302007 status = wlan_hdd_validate_context(pHddCtx);
2008 if (0 != status)
2009 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302010 return -EINVAL ;
2011 }
2012
2013 if (NULL == pAdapter)
2014 {
2015 hddLog(VOS_TRACE_LEVEL_FATAL,
2016 "%s: HDD adapter is Null", __func__);
2017 return -ENODEV;
2018 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302019
2020 if (pHddStaCtx == NULL)
2021 {
2022 hddLog(VOS_TRACE_LEVEL_FATAL,
2023 "%s: HddStaCtx is Null", __func__);
2024 return -ENODEV;
2025 }
2026
Dino Mycledf0a5d92014-07-04 09:41:55 +05302027 /* check the LLStats Capability */
2028 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2029 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2030 {
2031 hddLog(VOS_TRACE_LEVEL_ERROR,
2032 FL("Link Layer Statistics not supported by Firmware"));
2033 return -EINVAL;
2034 }
2035
Sunil Duttc69bccb2014-05-26 21:30:20 +05302036
2037 if (!pAdapter->isLinkLayerStatsSet)
2038 {
2039 hddLog(VOS_TRACE_LEVEL_FATAL,
2040 "%s: isLinkLayerStatsSet : %d",
2041 __func__, pAdapter->isLinkLayerStatsSet);
2042 return -EINVAL;
2043 }
2044
Mukul Sharma10313ba2015-07-29 19:14:39 +05302045 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2046 {
2047 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2048 "%s: Roaming in progress, so unable to proceed this request", __func__);
2049 return -EBUSY;
2050 }
2051
Sunil Duttc69bccb2014-05-26 21:30:20 +05302052 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2053 (struct nlattr *)data,
2054 data_len, qca_wlan_vendor_ll_get_policy))
2055 {
2056 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2057 return -EINVAL;
2058 }
2059
2060 if (!tb_vendor
2061 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2062 {
2063 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2064 return -EINVAL;
2065 }
2066
2067 if (!tb_vendor
2068 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2069 {
2070 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2071 return -EINVAL;
2072 }
2073
Sunil Duttc69bccb2014-05-26 21:30:20 +05302074
Dino Mycledf0a5d92014-07-04 09:41:55 +05302075 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302076 nla_get_u32( tb_vendor[
2077 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302078 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302079 nla_get_u32( tb_vendor[
2080 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2081
Dino Mycled3d50022014-07-07 12:58:25 +05302082 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2083 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302084
2085 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302086 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302087 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302088 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302089 hddLog(VOS_TRACE_LEVEL_INFO,
2090 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302091 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302092
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302093 spin_lock(&hdd_context_lock);
2094 context = &pHddCtx->ll_stats_context;
2095 context->request_id = linkLayerStatsGetReq.reqId;
2096 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
2097 INIT_COMPLETION(context->response_event);
2098 spin_unlock(&hdd_context_lock);
2099
Sunil Duttc69bccb2014-05-26 21:30:20 +05302100 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302101 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302102 {
2103 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2104 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302105 return -EINVAL;
2106 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302107
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302108 rc = wait_for_completion_timeout(&context->response_event,
2109 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
2110 if (!rc)
2111 {
2112 hddLog(LOGE,
2113 FL("Target response timed out request id %d request bitmap 0x%x"),
2114 context->request_id, context->request_bitmap);
2115 return -ETIMEDOUT;
2116 }
2117
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302118 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302119 return 0;
2120}
2121
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302122static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2123 struct wireless_dev *wdev,
2124 const void *data,
2125 int data_len)
2126{
2127 int ret = 0;
2128
2129 vos_ssr_protect(__func__);
2130 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
2131 vos_ssr_unprotect(__func__);
2132
2133 return ret;
2134}
2135
Sunil Duttc69bccb2014-05-26 21:30:20 +05302136const struct
2137nla_policy
2138qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
2139{
2140 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
2141 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
2142 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
2143 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
2144};
2145
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302146static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2147 struct wireless_dev *wdev,
2148 const void *data,
2149 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302150{
2151 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2152 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302153 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302154 struct net_device *dev = wdev->netdev;
2155 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2156 u32 statsClearReqMask;
2157 u8 stopReq;
2158 int status;
2159
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302160 ENTER();
2161
Sunil Duttc69bccb2014-05-26 21:30:20 +05302162 status = wlan_hdd_validate_context(pHddCtx);
2163 if (0 != status)
2164 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302165 return -EINVAL;
2166 }
2167
2168 if (NULL == pAdapter)
2169 {
2170 hddLog(VOS_TRACE_LEVEL_FATAL,
2171 "%s: HDD adapter is Null", __func__);
2172 return -ENODEV;
2173 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302174 /* check the LLStats Capability */
2175 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2176 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2177 {
2178 hddLog(VOS_TRACE_LEVEL_ERROR,
2179 FL("Enable LLStats Capability"));
2180 return -EINVAL;
2181 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302182
2183 if (!pAdapter->isLinkLayerStatsSet)
2184 {
2185 hddLog(VOS_TRACE_LEVEL_FATAL,
2186 "%s: isLinkLayerStatsSet : %d",
2187 __func__, pAdapter->isLinkLayerStatsSet);
2188 return -EINVAL;
2189 }
2190
2191 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2192 (struct nlattr *)data,
2193 data_len, qca_wlan_vendor_ll_clr_policy))
2194 {
2195 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2196 return -EINVAL;
2197 }
2198
2199 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2200
2201 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2202 {
2203 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2204 return -EINVAL;
2205
2206 }
2207
Sunil Duttc69bccb2014-05-26 21:30:20 +05302208
Dino Mycledf0a5d92014-07-04 09:41:55 +05302209 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302210 nla_get_u32(
2211 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2212
Dino Mycledf0a5d92014-07-04 09:41:55 +05302213 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302214 nla_get_u8(
2215 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2216
2217 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302218 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302219
Dino Mycled3d50022014-07-07 12:58:25 +05302220 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2221 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302222
2223 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302224 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302225 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302226 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302227 hddLog(VOS_TRACE_LEVEL_INFO,
2228 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302229 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302230 hddLog(VOS_TRACE_LEVEL_INFO,
2231 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302232 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302233
2234 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302235 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302236 {
2237 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302238 hdd_station_ctx_t *pHddStaCtx;
2239
2240 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2241 if (VOS_STATUS_SUCCESS !=
2242 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2243 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2244 {
2245 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2246 "WLANTL_ClearInterfaceStats Failed", __func__);
2247 return -EINVAL;
2248 }
2249 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2250 (statsClearReqMask & WIFI_STATS_IFACE)) {
2251 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2252 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2253 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2254 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2255 }
2256
Sunil Duttc69bccb2014-05-26 21:30:20 +05302257 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2258 2 * sizeof(u32) +
2259 NLMSG_HDRLEN);
2260
2261 if (temp_skbuff != NULL)
2262 {
2263
2264 if (nla_put_u32(temp_skbuff,
2265 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2266 statsClearReqMask) ||
2267 nla_put_u32(temp_skbuff,
2268 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2269 stopReq))
2270 {
2271 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2272 kfree_skb(temp_skbuff);
2273 return -EINVAL;
2274 }
2275 /* If the ask is to stop the stats collection as part of clear
2276 * (stopReq = 1) , ensure that no further requests of get
2277 * go to the firmware by having isLinkLayerStatsSet set to 0.
2278 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302279 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302280 * case the firmware is just asked to clear the statistics.
2281 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302282 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302283 pAdapter->isLinkLayerStatsSet = 0;
2284 return cfg80211_vendor_cmd_reply(temp_skbuff);
2285 }
2286 return -ENOMEM;
2287 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302288
2289 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302290 return -EINVAL;
2291}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302292static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2293 struct wireless_dev *wdev,
2294 const void *data,
2295 int data_len)
2296{
2297 int ret = 0;
2298
2299 vos_ssr_protect(__func__);
2300 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2301 vos_ssr_unprotect(__func__);
2302
2303 return ret;
2304
2305
2306}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302307#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2308
Dino Mycle6fb96c12014-06-10 11:52:40 +05302309#ifdef WLAN_FEATURE_EXTSCAN
2310static const struct nla_policy
2311wlan_hdd_extscan_config_policy
2312 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2313{
2314 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2315 { .type = NLA_U32 },
2316 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2317 { .type = NLA_U32 },
2318 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2319 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2320 { .type = NLA_U32 },
2321 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2322 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2323
2324 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2325 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2326 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2327 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2328 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302329 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2330 { .type = NLA_U32 },
2331 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2332 { .type = NLA_U32 },
2333 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2334 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302335 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2336 { .type = NLA_U32 },
2337 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2338 { .type = NLA_U32 },
2339 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2340 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302341 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2342 { .type = NLA_U8 },
2343 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302344 { .type = NLA_U8 },
2345 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2346 { .type = NLA_U8 },
2347 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2348 { .type = NLA_U8 },
2349
2350 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2351 { .type = NLA_U32 },
2352 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2353 { .type = NLA_UNSPEC },
2354 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2355 { .type = NLA_S32 },
2356 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2357 { .type = NLA_S32 },
2358 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2359 { .type = NLA_U32 },
2360 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2361 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302362 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2363 { .type = NLA_U32 },
2364 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2365 { .type = NLA_BINARY,
2366 .len = IEEE80211_MAX_SSID_LEN + 1 },
2367 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302368 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302369 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2370 { .type = NLA_U32 },
2371 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2372 { .type = NLA_U8 },
2373 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2374 { .type = NLA_S32 },
2375 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2376 { .type = NLA_S32 },
2377 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2378 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302379};
2380
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302381/**
2382 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2383 * @ctx: hdd global context
2384 * @data: capabilities data
2385 *
2386 * Return: none
2387 */
2388static void
2389wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302390{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302391 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302392 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302393 tSirEXTScanCapabilitiesEvent *data =
2394 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302395
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302396 ENTER();
2397
2398 if (wlan_hdd_validate_context(pHddCtx))
2399 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302400 return;
2401 }
2402
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302403 if (!pMsg)
2404 {
2405 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2406 return;
2407 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302408
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302409 vos_spin_lock_acquire(&hdd_context_lock);
2410
2411 context = &pHddCtx->ext_scan_context;
2412 /* validate response received from target*/
2413 if (context->request_id != data->requestId)
2414 {
2415 vos_spin_lock_release(&hdd_context_lock);
2416 hddLog(LOGE,
2417 FL("Target response id did not match: request_id %d resposne_id %d"),
2418 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302419 return;
2420 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302421 else
2422 {
2423 context->capability_response = *data;
2424 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302425 }
2426
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302427 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302428
Dino Mycle6fb96c12014-06-10 11:52:40 +05302429 return;
2430}
2431
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302432/*
2433 * define short names for the global vendor params
2434 * used by wlan_hdd_send_ext_scan_capability()
2435 */
2436#define PARAM_REQUEST_ID \
2437 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2438#define PARAM_STATUS \
2439 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2440#define MAX_SCAN_CACHE_SIZE \
2441 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2442#define MAX_SCAN_BUCKETS \
2443 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2444#define MAX_AP_CACHE_PER_SCAN \
2445 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2446#define MAX_RSSI_SAMPLE_SIZE \
2447 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2448#define MAX_SCAN_RPT_THRHOLD \
2449 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2450#define MAX_HOTLIST_BSSIDS \
2451 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2452#define MAX_BSSID_HISTORY_ENTRIES \
2453 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2454#define MAX_HOTLIST_SSIDS \
2455 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302456#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2457 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302458
2459static int wlan_hdd_send_ext_scan_capability(void *ctx)
2460{
2461 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2462 struct sk_buff *skb = NULL;
2463 int ret;
2464 tSirEXTScanCapabilitiesEvent *data;
2465 tANI_U32 nl_buf_len;
2466
2467 ret = wlan_hdd_validate_context(pHddCtx);
2468 if (0 != ret)
2469 {
2470 return ret;
2471 }
2472
2473 data = &(pHddCtx->ext_scan_context.capability_response);
2474
2475 nl_buf_len = NLMSG_HDRLEN;
2476 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2477 (sizeof(data->status) + NLA_HDRLEN) +
2478 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2479 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2480 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2481 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2482 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2483 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2484 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2485 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2486
2487 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2488
2489 if (!skb)
2490 {
2491 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2492 return -ENOMEM;
2493 }
2494
2495 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2496 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2497 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2498 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2499 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2500 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2501 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2502 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2503
2504 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2505 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2506 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2507 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2508 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2509 data->maxApPerScan) ||
2510 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2511 data->maxRssiSampleSize) ||
2512 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2513 data->maxScanReportingThreshold) ||
2514 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2515 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2516 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302517 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2518 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302519 {
2520 hddLog(LOGE, FL("nla put fail"));
2521 goto nla_put_failure;
2522 }
2523
2524 cfg80211_vendor_cmd_reply(skb);
2525 return 0;
2526
2527nla_put_failure:
2528 kfree_skb(skb);
2529 return -EINVAL;;
2530}
2531
2532/*
2533 * done with short names for the global vendor params
2534 * used by wlan_hdd_send_ext_scan_capability()
2535 */
2536#undef PARAM_REQUEST_ID
2537#undef PARAM_STATUS
2538#undef MAX_SCAN_CACHE_SIZE
2539#undef MAX_SCAN_BUCKETS
2540#undef MAX_AP_CACHE_PER_SCAN
2541#undef MAX_RSSI_SAMPLE_SIZE
2542#undef MAX_SCAN_RPT_THRHOLD
2543#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302544#undef MAX_BSSID_HISTORY_ENTRIES
2545#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302546
2547static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2548{
2549 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2550 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302551 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302552 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302553
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302554 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302555
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302556 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302557 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302558
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302559 if (!pMsg)
2560 {
2561 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302562 return;
2563 }
2564
Dino Mycle6fb96c12014-06-10 11:52:40 +05302565 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2566 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2567
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302568 context = &pHddCtx->ext_scan_context;
2569 spin_lock(&hdd_context_lock);
2570 if (context->request_id == pData->requestId) {
2571 context->response_status = pData->status ? -EINVAL : 0;
2572 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302573 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302574 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302575
2576 /*
2577 * Store the Request ID for comparing with the requestID obtained
2578 * in other requests.HDD shall return a failure is the extscan_stop
2579 * request is issued with a different requestId as that of the
2580 * extscan_start request. Also, This requestId shall be used while
2581 * indicating the full scan results to the upper layers.
2582 * The requestId is stored with the assumption that the firmware
2583 * shall return the ext scan start request's requestId in ext scan
2584 * start response.
2585 */
2586 if (pData->status == 0)
2587 pMac->sme.extScanStartReqId = pData->requestId;
2588
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302589 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302590 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302591}
2592
2593
2594static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2595{
2596 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2597 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302598 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302599
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302600 ENTER();
2601
2602 if (wlan_hdd_validate_context(pHddCtx)){
2603 return;
2604 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302605
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302606 if (!pMsg)
2607 {
2608 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302609 return;
2610 }
2611
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302612 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2613 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302614
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302615 context = &pHddCtx->ext_scan_context;
2616 spin_lock(&hdd_context_lock);
2617 if (context->request_id == pData->requestId) {
2618 context->response_status = pData->status ? -EINVAL : 0;
2619 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302620 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302621 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302622
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302623 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302624 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302625}
2626
Dino Mycle6fb96c12014-06-10 11:52:40 +05302627static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2628 void *pMsg)
2629{
2630 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302631 tpSirEXTScanSetBssidHotListRspParams pData =
2632 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302633 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302634
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302635 ENTER();
2636
2637 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302638 return;
2639 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302640
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302641 if (!pMsg)
2642 {
2643 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2644 return;
2645 }
2646
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302647 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2648 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302649
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302650 context = &pHddCtx->ext_scan_context;
2651 spin_lock(&hdd_context_lock);
2652 if (context->request_id == pData->requestId) {
2653 context->response_status = pData->status ? -EINVAL : 0;
2654 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302655 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302656 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302657
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302658 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302659 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302660}
2661
2662static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2663 void *pMsg)
2664{
2665 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302666 tpSirEXTScanResetBssidHotlistRspParams pData =
2667 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302668 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302669
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302670 ENTER();
2671
2672 if (wlan_hdd_validate_context(pHddCtx)) {
2673 return;
2674 }
2675 if (!pMsg)
2676 {
2677 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302678 return;
2679 }
2680
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302681 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2682 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302683
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302684 context = &pHddCtx->ext_scan_context;
2685 spin_lock(&hdd_context_lock);
2686 if (context->request_id == pData->requestId) {
2687 context->response_status = pData->status ? -EINVAL : 0;
2688 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302689 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302690 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302691
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302692 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302693 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302694}
2695
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302696static void wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(void *ctx,
2697 void *pMsg)
2698{
2699 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2700 tpSirEXTScanSetSsidHotListRspParams pData =
2701 (tpSirEXTScanSetSsidHotListRspParams) pMsg;
2702 struct hdd_ext_scan_context *context;
2703
2704 if (wlan_hdd_validate_context(pHddCtx)){
2705 return;
2706 }
2707
2708 if (!pMsg)
2709 {
2710 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2711 return;
2712 }
2713
2714 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2715 pData->status);
2716
2717 context = &pHddCtx->ext_scan_context;
2718 spin_lock(&hdd_context_lock);
2719 if (context->request_id == pData->requestId) {
2720 context->response_status = pData->status ? -EINVAL : 0;
2721 complete(&context->response_event);
2722 }
2723 spin_unlock(&hdd_context_lock);
2724
2725 return;
2726}
2727
2728static void wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(void *ctx,
2729 void *pMsg)
2730{
2731 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2732 tpSirEXTScanResetSsidHotlistRspParams pData =
2733 (tpSirEXTScanResetSsidHotlistRspParams) pMsg;
2734 struct hdd_ext_scan_context *context;
2735
2736 if (wlan_hdd_validate_context(pHddCtx)) {
2737 return;
2738 }
2739 if (!pMsg)
2740 {
2741 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2742 return;
2743 }
2744
2745 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2746 pData->status);
2747
2748 context = &pHddCtx->ext_scan_context;
2749 spin_lock(&hdd_context_lock);
2750 if (context->request_id == pData->requestId) {
2751 context->response_status = pData->status ? -EINVAL : 0;
2752 complete(&context->response_event);
2753 }
2754 spin_unlock(&hdd_context_lock);
2755
2756 return;
2757}
2758
2759
Dino Mycle6fb96c12014-06-10 11:52:40 +05302760static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2761 void *pMsg)
2762{
2763 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2764 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302765 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302766 tANI_S32 totalResults;
2767 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302768 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
2769 struct hdd_ext_scan_context *context;
2770 bool ignore_cached_results = false;
2771 tExtscanCachedScanResult *result;
2772 struct nlattr *nla_results;
2773 tANI_U16 ieLength= 0;
2774 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302775
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302776 ENTER();
2777
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302778 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302779 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302780
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302781 if (!pMsg)
2782 {
2783 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2784 return;
2785 }
2786
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302787 spin_lock(&hdd_context_lock);
2788 context = &pHddCtx->ext_scan_context;
2789 ignore_cached_results = context->ignore_cached_results;
2790 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302791
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302792 if (ignore_cached_results) {
2793 hddLog(LOGE,
2794 FL("Ignore the cached results received after timeout"));
2795 return;
2796 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302797
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302798 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
2799 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302800
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302801 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302802
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302803 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
2804 scan_id_index++) {
2805 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302806
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302807 totalResults = result->num_results;
2808 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
2809 result->scan_id, result->flags, totalResults);
2810 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302811
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302812 do{
2813 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2814 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2815 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302816
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302817 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2818 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
2819
2820 if (!skb) {
2821 hddLog(VOS_TRACE_LEVEL_ERROR,
2822 FL("cfg80211_vendor_event_alloc failed"));
2823 return;
2824 }
2825
2826 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2827
2828 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2829 pData->requestId) ||
2830 nla_put_u32(skb,
2831 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2832 resultsPerEvent)) {
2833 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2834 goto fail;
2835 }
2836 if (nla_put_u8(skb,
2837 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2838 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302839 {
2840 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2841 goto fail;
2842 }
2843
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302844 if (nla_put_u32(skb,
2845 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2846 result->scan_id)) {
2847 hddLog(LOGE, FL("put fail"));
2848 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302849 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302850
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302851 nla_results = nla_nest_start(skb,
2852 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
2853 if (!nla_results)
2854 goto fail;
2855
2856 if (resultsPerEvent) {
2857 struct nlattr *aps;
2858 struct nlattr *nla_result;
2859
2860 nla_result = nla_nest_start(skb, scan_id_index);
2861 if(!nla_result)
2862 goto fail;
2863
2864 if (nla_put_u32(skb,
2865 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2866 result->scan_id) ||
2867 nla_put_u32(skb,
2868 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
2869 result->flags) ||
2870 nla_put_u32(skb,
2871 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2872 totalResults)) {
2873 hddLog(LOGE, FL("put fail"));
2874 goto fail;
2875 }
2876
2877 aps = nla_nest_start(skb,
2878 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2879 if (!aps)
2880 {
2881 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2882 goto fail;
2883 }
2884
2885 head_ptr = (tpSirWifiScanResult) &(result->ap);
2886
2887 for (j = 0; j < resultsPerEvent; j++, i++) {
2888 struct nlattr *ap;
2889 pSirWifiScanResult = head_ptr + i;
2890
2891 /*
2892 * Firmware returns timestamp from WiFi turn ON till
2893 * BSSID was cached (in seconds). Add this with
2894 * time gap between system boot up to WiFi turn ON
2895 * to derive the time since boot when the
2896 * BSSID was cached.
2897 */
2898 pSirWifiScanResult->ts += pHddCtx->wifi_turn_on_time_since_boot;
2899 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2900 "Ssid (%s)"
2901 "Bssid: %pM "
2902 "Channel (%u)"
2903 "Rssi (%d)"
2904 "RTT (%u)"
2905 "RTT_SD (%u)"
2906 "Beacon Period %u"
2907 "Capability 0x%x "
2908 "Ie length %d",
2909 i,
2910 pSirWifiScanResult->ts,
2911 pSirWifiScanResult->ssid,
2912 pSirWifiScanResult->bssid,
2913 pSirWifiScanResult->channel,
2914 pSirWifiScanResult->rssi,
2915 pSirWifiScanResult->rtt,
2916 pSirWifiScanResult->rtt_sd,
2917 pSirWifiScanResult->beaconPeriod,
2918 pSirWifiScanResult->capability,
2919 ieLength);
2920
2921 ap = nla_nest_start(skb, j + 1);
2922 if (!ap)
2923 {
2924 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2925 goto fail;
2926 }
2927
2928 if (nla_put_u64(skb,
2929 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2930 pSirWifiScanResult->ts) )
2931 {
2932 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2933 goto fail;
2934 }
2935 if (nla_put(skb,
2936 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2937 sizeof(pSirWifiScanResult->ssid),
2938 pSirWifiScanResult->ssid) )
2939 {
2940 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2941 goto fail;
2942 }
2943 if (nla_put(skb,
2944 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2945 sizeof(pSirWifiScanResult->bssid),
2946 pSirWifiScanResult->bssid) )
2947 {
2948 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2949 goto fail;
2950 }
2951 if (nla_put_u32(skb,
2952 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2953 pSirWifiScanResult->channel) )
2954 {
2955 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2956 goto fail;
2957 }
2958 if (nla_put_s32(skb,
2959 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2960 pSirWifiScanResult->rssi) )
2961 {
2962 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2963 goto fail;
2964 }
2965 if (nla_put_u32(skb,
2966 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2967 pSirWifiScanResult->rtt) )
2968 {
2969 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2970 goto fail;
2971 }
2972 if (nla_put_u32(skb,
2973 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2974 pSirWifiScanResult->rtt_sd))
2975 {
2976 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2977 goto fail;
2978 }
2979 if (nla_put_u32(skb,
2980 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2981 pSirWifiScanResult->beaconPeriod))
2982 {
2983 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2984 goto fail;
2985 }
2986 if (nla_put_u32(skb,
2987 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2988 pSirWifiScanResult->capability))
2989 {
2990 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2991 goto fail;
2992 }
2993 if (nla_put_u32(skb,
2994 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2995 ieLength))
2996 {
2997 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2998 goto fail;
2999 }
3000
3001 if (ieLength)
3002 if (nla_put(skb,
3003 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3004 ieLength, ie)) {
3005 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3006 goto fail;
3007 }
3008
3009 nla_nest_end(skb, ap);
3010 }
3011 nla_nest_end(skb, aps);
3012 nla_nest_end(skb, nla_result);
3013 }
3014
3015 nla_nest_end(skb, nla_results);
3016
3017 cfg80211_vendor_cmd_reply(skb);
3018
3019 } while (totalResults > 0);
3020 }
3021
3022 if (!pData->moreData) {
3023 spin_lock(&hdd_context_lock);
3024 context->response_status = 0;
3025 complete(&context->response_event);
3026 spin_unlock(&hdd_context_lock);
3027 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303028
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303029 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303030 return;
3031fail:
3032 kfree_skb(skb);
3033 return;
3034}
3035
3036static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3037 void *pMsg)
3038{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303039 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303040 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3041 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303042 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303043
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303044 ENTER();
3045
3046 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303047 hddLog(LOGE,
3048 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303049 return;
3050 }
3051 if (!pMsg)
3052 {
3053 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303054 return;
3055 }
3056
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303057 if (pData->bss_found)
3058 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
3059 else
3060 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
3061
Dino Mycle6fb96c12014-06-10 11:52:40 +05303062 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303063#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3064 NULL,
3065#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303066 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303067 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303068
3069 if (!skb) {
3070 hddLog(VOS_TRACE_LEVEL_ERROR,
3071 FL("cfg80211_vendor_event_alloc failed"));
3072 return;
3073 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303074
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303075 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3076 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
3077 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3078 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
3079
3080 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303081 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3082 "Ssid (%s) "
3083 "Bssid (" MAC_ADDRESS_STR ") "
3084 "Channel (%u) "
3085 "Rssi (%d) "
3086 "RTT (%u) "
3087 "RTT_SD (%u) ",
3088 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303089 pData->bssHotlist[i].ts,
3090 pData->bssHotlist[i].ssid,
3091 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
3092 pData->bssHotlist[i].channel,
3093 pData->bssHotlist[i].rssi,
3094 pData->bssHotlist[i].rtt,
3095 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303096 }
3097
3098 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3099 pData->requestId) ||
3100 nla_put_u32(skb,
3101 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303102 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303103 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3104 goto fail;
3105 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303106 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303107 struct nlattr *aps;
3108
3109 aps = nla_nest_start(skb,
3110 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3111 if (!aps)
3112 goto fail;
3113
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303114 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303115 struct nlattr *ap;
3116
3117 ap = nla_nest_start(skb, i + 1);
3118 if (!ap)
3119 goto fail;
3120
3121 if (nla_put_u64(skb,
3122 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303123 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303124 nla_put(skb,
3125 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303126 sizeof(pData->bssHotlist[i].ssid),
3127 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303128 nla_put(skb,
3129 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303130 sizeof(pData->bssHotlist[i].bssid),
3131 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303132 nla_put_u32(skb,
3133 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303134 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303135 nla_put_s32(skb,
3136 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303137 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303138 nla_put_u32(skb,
3139 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303140 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05303141 nla_put_u32(skb,
3142 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303143 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303144 goto fail;
3145
3146 nla_nest_end(skb, ap);
3147 }
3148 nla_nest_end(skb, aps);
3149
3150 if (nla_put_u8(skb,
3151 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3152 pData->moreData))
3153 goto fail;
3154 }
3155
3156 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303157 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303158 return;
3159
3160fail:
3161 kfree_skb(skb);
3162 return;
3163
3164}
Dino Mycle6fb96c12014-06-10 11:52:40 +05303165
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303166/**
3167 * wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind() -
3168 * Handle an SSID hotlist match event
3169 * @ctx: HDD context registered with SME
3170 * @event: The SSID hotlist match event
3171 *
3172 * This function will take an SSID match event that was generated by
3173 * firmware and will convert it into a cfg80211 vendor event which is
3174 * sent to userspace.
3175 *
3176 * Return: none
3177 */
3178static void
3179wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
3180 void *pMsg)
3181{
3182 hdd_context_t *hdd_ctx = ctx;
3183 struct sk_buff *skb;
3184 tANI_U32 i, index;
3185 tpSirEXTScanSsidHotlistMatch pData = (tpSirEXTScanSsidHotlistMatch) pMsg;
3186
3187 ENTER();
3188
3189 if (wlan_hdd_validate_context(hdd_ctx)) {
3190 hddLog(LOGE,
3191 FL("HDD context is not valid or response"));
3192 return;
3193 }
3194 if (!pMsg)
3195 {
3196 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3197 return;
3198 }
3199
3200 if (pData->ssid_found) {
3201 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX;
3202 hddLog(LOG1, "SSID hotlist found");
3203 } else {
3204 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX;
3205 hddLog(LOG1, "SSID hotlist lost");
3206 }
3207
3208 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
3209#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3210 NULL,
3211#endif
3212 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3213 index, GFP_KERNEL);
3214
3215 if (!skb) {
3216 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
3217 return;
3218 }
3219 hddLog(LOG1, "Req Id %u, Num of SSIDs %u, More Data (%u)",
3220 pData->requestId, pData->numHotlistSsid, pData->moreData);
3221
3222 for (i = 0; i < pData->numHotlistSsid; i++) {
3223 hddLog(LOG1, "[i=%d] Timestamp %llu "
3224 "Ssid: %s "
3225 "Bssid (" MAC_ADDRESS_STR ") "
3226 "Channel %u "
3227 "Rssi %d "
3228 "RTT %u "
3229 "RTT_SD %u",
3230 i,
3231 pData->ssidHotlist[i].ts,
3232 pData->ssidHotlist[i].ssid,
3233 MAC_ADDR_ARRAY(pData->ssidHotlist[i].bssid),
3234 pData->ssidHotlist[i].channel,
3235 pData->ssidHotlist[i].rssi,
3236 pData->ssidHotlist[i].rtt,
3237 pData->ssidHotlist[i].rtt_sd);
3238 }
3239
3240 if (nla_put_u32(skb,
3241 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3242 pData->requestId) ||
3243 nla_put_u32(skb,
3244 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3245 pData->numHotlistSsid)) {
3246 hddLog(LOGE, FL("put fail"));
3247 goto fail;
3248 }
3249
3250 if (pData->numHotlistSsid) {
3251 struct nlattr *aps;
3252 aps = nla_nest_start(skb,
3253 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3254 if (!aps) {
3255 hddLog(LOGE, FL("nest fail"));
3256 goto fail;
3257 }
3258
3259 for (i = 0; i < pData->numHotlistSsid; i++) {
3260 struct nlattr *ap;
3261
3262 ap = nla_nest_start(skb, i);
3263 if (!ap) {
3264 hddLog(LOGE, FL("nest fail"));
3265 goto fail;
3266 }
3267
3268 if (nla_put_u64(skb,
3269 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3270 pData->ssidHotlist[i].ts) ||
3271 nla_put(skb,
3272 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3273 sizeof(pData->ssidHotlist[i].ssid),
3274 pData->ssidHotlist[i].ssid) ||
3275 nla_put(skb,
3276 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3277 sizeof(pData->ssidHotlist[i].bssid),
3278 pData->ssidHotlist[i].bssid) ||
3279 nla_put_u32(skb,
3280 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3281 pData->ssidHotlist[i].channel) ||
3282 nla_put_s32(skb,
3283 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3284 pData->ssidHotlist[i].rssi) ||
3285 nla_put_u32(skb,
3286 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3287 pData->ssidHotlist[i].rtt) ||
3288 nla_put_u32(skb,
3289 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3290 pData->ssidHotlist[i].rtt_sd)) {
3291 hddLog(LOGE, FL("put fail"));
3292 goto fail;
3293 }
3294 nla_nest_end(skb, ap);
3295 }
3296 nla_nest_end(skb, aps);
3297
3298 if (nla_put_u8(skb,
3299 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3300 pData->moreData)) {
3301 hddLog(LOGE, FL("put fail"));
3302 goto fail;
3303 }
3304 }
3305
3306 cfg80211_vendor_event(skb, GFP_KERNEL);
3307 return;
3308
3309fail:
3310 kfree_skb(skb);
3311 return;
3312
3313}
3314
3315
Dino Mycle6fb96c12014-06-10 11:52:40 +05303316static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3317 void *pMsg)
3318{
3319 struct sk_buff *skb;
3320 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3321 tpSirWifiFullScanResultEvent pData =
3322 (tpSirWifiFullScanResultEvent) (pMsg);
3323
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303324 ENTER();
3325
3326 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303327 hddLog(LOGE,
3328 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303329 return;
3330 }
3331 if (!pMsg)
3332 {
3333 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303334 return;
3335 }
3336
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303337 /*
3338 * If the full scan result including IE data exceeds NL 4K size
3339 * limitation, drop that beacon/probe rsp frame.
3340 */
3341 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3342 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3343 return;
3344 }
3345
Dino Mycle6fb96c12014-06-10 11:52:40 +05303346 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303347#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3348 NULL,
3349#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303350 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3351 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3352 GFP_KERNEL);
3353
3354 if (!skb) {
3355 hddLog(VOS_TRACE_LEVEL_ERROR,
3356 FL("cfg80211_vendor_event_alloc failed"));
3357 return;
3358 }
3359
Dino Mycle6fb96c12014-06-10 11:52:40 +05303360 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3361 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3362 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3363 "Ssid (%s)"
3364 "Bssid (" MAC_ADDRESS_STR ")"
3365 "Channel (%u)"
3366 "Rssi (%d)"
3367 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303368 "RTT_SD (%u)"
3369 "Bcn Period %d"
3370 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303371 pData->ap.ts,
3372 pData->ap.ssid,
3373 MAC_ADDR_ARRAY(pData->ap.bssid),
3374 pData->ap.channel,
3375 pData->ap.rssi,
3376 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303377 pData->ap.rtt_sd,
3378 pData->ap.beaconPeriod,
3379 pData->ap.capability);
3380
Dino Mycle6fb96c12014-06-10 11:52:40 +05303381 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3382 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3383 pData->requestId) ||
3384 nla_put_u64(skb,
3385 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3386 pData->ap.ts) ||
3387 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3388 sizeof(pData->ap.ssid),
3389 pData->ap.ssid) ||
3390 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3391 WNI_CFG_BSSID_LEN,
3392 pData->ap.bssid) ||
3393 nla_put_u32(skb,
3394 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3395 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303396 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303397 pData->ap.rssi) ||
3398 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3399 pData->ap.rtt) ||
3400 nla_put_u32(skb,
3401 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3402 pData->ap.rtt_sd) ||
3403 nla_put_u16(skb,
3404 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3405 pData->ap.beaconPeriod) ||
3406 nla_put_u16(skb,
3407 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3408 pData->ap.capability) ||
3409 nla_put_u32(skb,
3410 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303411 pData->ieLength) ||
3412 nla_put_u8(skb,
3413 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3414 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303415 {
3416 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3417 goto nla_put_failure;
3418 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303419
3420 if (pData->ieLength) {
3421 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3422 pData->ieLength,
3423 pData->ie))
3424 {
3425 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3426 goto nla_put_failure;
3427 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303428 }
3429
3430 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303431 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303432 return;
3433
3434nla_put_failure:
3435 kfree_skb(skb);
3436 return;
3437}
3438
3439static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3440 void *pMsg)
3441{
3442 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3443 struct sk_buff *skb = NULL;
3444 tpSirEXTScanResultsAvailableIndParams pData =
3445 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3446
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303447 ENTER();
3448
3449 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303450 hddLog(LOGE,
3451 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303452 return;
3453 }
3454 if (!pMsg)
3455 {
3456 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303457 return;
3458 }
3459
3460 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303461#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3462 NULL,
3463#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303464 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3465 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3466 GFP_KERNEL);
3467
3468 if (!skb) {
3469 hddLog(VOS_TRACE_LEVEL_ERROR,
3470 FL("cfg80211_vendor_event_alloc failed"));
3471 return;
3472 }
3473
Dino Mycle6fb96c12014-06-10 11:52:40 +05303474 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3475 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3476 pData->numResultsAvailable);
3477 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3478 pData->requestId) ||
3479 nla_put_u32(skb,
3480 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3481 pData->numResultsAvailable)) {
3482 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3483 goto nla_put_failure;
3484 }
3485
3486 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303487 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303488 return;
3489
3490nla_put_failure:
3491 kfree_skb(skb);
3492 return;
3493}
3494
3495static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3496{
3497 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3498 struct sk_buff *skb = NULL;
3499 tpSirEXTScanProgressIndParams pData =
3500 (tpSirEXTScanProgressIndParams) pMsg;
3501
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303502 ENTER();
3503
3504 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303505 hddLog(LOGE,
3506 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303507 return;
3508 }
3509 if (!pMsg)
3510 {
3511 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303512 return;
3513 }
3514
3515 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303516#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3517 NULL,
3518#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303519 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3520 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3521 GFP_KERNEL);
3522
3523 if (!skb) {
3524 hddLog(VOS_TRACE_LEVEL_ERROR,
3525 FL("cfg80211_vendor_event_alloc failed"));
3526 return;
3527 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303528 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303529 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3530 pData->extScanEventType);
3531 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3532 pData->status);
3533
3534 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3535 pData->extScanEventType) ||
3536 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303537 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3538 pData->requestId) ||
3539 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303540 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3541 pData->status)) {
3542 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3543 goto nla_put_failure;
3544 }
3545
3546 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303547 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303548 return;
3549
3550nla_put_failure:
3551 kfree_skb(skb);
3552 return;
3553}
3554
3555void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3556 void *pMsg)
3557{
3558 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3559
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303560 ENTER();
3561
Dino Mycle6fb96c12014-06-10 11:52:40 +05303562 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303563 return;
3564 }
3565
3566 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3567
3568
3569 switch(evType) {
3570 case SIR_HAL_EXTSCAN_START_RSP:
3571 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3572 break;
3573
3574 case SIR_HAL_EXTSCAN_STOP_RSP:
3575 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3576 break;
3577 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3578 /* There is no need to send this response to upper layer
3579 Just log the message */
3580 hddLog(VOS_TRACE_LEVEL_INFO,
3581 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3582 break;
3583 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3584 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3585 break;
3586
3587 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3588 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3589 break;
3590
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303591 case SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP:
3592 wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(ctx, pMsg);
3593 break;
3594
3595 case SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP:
3596 wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(ctx, pMsg);
3597 break;
3598
Dino Mycle6fb96c12014-06-10 11:52:40 +05303599 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303600 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303601 break;
3602 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3603 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3604 break;
3605 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3606 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3607 break;
3608 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3609 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3610 break;
3611 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3612 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3613 break;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303614 case SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND:
3615 wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(ctx, pMsg);
3616 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303617 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3618 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3619 break;
3620 default:
3621 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3622 break;
3623 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303624 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303625}
3626
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303627static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3628 struct wireless_dev *wdev,
3629 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303630{
Dino Myclee8843b32014-07-04 14:21:45 +05303631 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303632 struct net_device *dev = wdev->netdev;
3633 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3634 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3635 struct nlattr
3636 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3637 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303638 struct hdd_ext_scan_context *context;
3639 unsigned long rc;
3640 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303641
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303642 ENTER();
3643
Dino Mycle6fb96c12014-06-10 11:52:40 +05303644 status = wlan_hdd_validate_context(pHddCtx);
3645 if (0 != status)
3646 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303647 return -EINVAL;
3648 }
Dino Myclee8843b32014-07-04 14:21:45 +05303649 /* check the EXTScan Capability */
3650 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3651 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3652 {
3653 hddLog(VOS_TRACE_LEVEL_ERROR,
3654 FL("EXTScan not enabled/supported by Firmware"));
3655 return -EINVAL;
3656 }
3657
Dino Mycle6fb96c12014-06-10 11:52:40 +05303658 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3659 data, dataLen,
3660 wlan_hdd_extscan_config_policy)) {
3661 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3662 return -EINVAL;
3663 }
3664
3665 /* Parse and fetch request Id */
3666 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3668 return -EINVAL;
3669 }
3670
Dino Myclee8843b32014-07-04 14:21:45 +05303671 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303672 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303673 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303674
Dino Myclee8843b32014-07-04 14:21:45 +05303675 reqMsg.sessionId = pAdapter->sessionId;
3676 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303677
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303678 vos_spin_lock_acquire(&hdd_context_lock);
3679 context = &pHddCtx->ext_scan_context;
3680 context->request_id = reqMsg.requestId;
3681 INIT_COMPLETION(context->response_event);
3682 vos_spin_lock_release(&hdd_context_lock);
3683
Dino Myclee8843b32014-07-04 14:21:45 +05303684 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303685 if (!HAL_STATUS_SUCCESS(status)) {
3686 hddLog(VOS_TRACE_LEVEL_ERROR,
3687 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303688 return -EINVAL;
3689 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303690
3691 rc = wait_for_completion_timeout(&context->response_event,
3692 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3693 if (!rc) {
3694 hddLog(LOGE, FL("Target response timed out"));
3695 return -ETIMEDOUT;
3696 }
3697
3698 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3699 if (ret)
3700 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3701
3702 return ret;
3703
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303704 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303705 return 0;
3706}
3707
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303708static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3709 struct wireless_dev *wdev,
3710 const void *data, int dataLen)
3711{
3712 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303713
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303714 vos_ssr_protect(__func__);
3715 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3716 vos_ssr_unprotect(__func__);
3717
3718 return ret;
3719}
3720
3721static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3722 struct wireless_dev *wdev,
3723 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303724{
Dino Myclee8843b32014-07-04 14:21:45 +05303725 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303726 struct net_device *dev = wdev->netdev;
3727 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3728 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3729 struct nlattr
3730 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3731 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303732 struct hdd_ext_scan_context *context;
3733 unsigned long rc;
3734 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303735
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303736 ENTER();
3737
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303738 if (VOS_FTM_MODE == hdd_get_conparam()) {
3739 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3740 return -EINVAL;
3741 }
3742
Dino Mycle6fb96c12014-06-10 11:52:40 +05303743 status = wlan_hdd_validate_context(pHddCtx);
3744 if (0 != status)
3745 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303746 return -EINVAL;
3747 }
Dino Myclee8843b32014-07-04 14:21:45 +05303748 /* check the EXTScan Capability */
3749 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3750 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3751 {
3752 hddLog(VOS_TRACE_LEVEL_ERROR,
3753 FL("EXTScan not enabled/supported by Firmware"));
3754 return -EINVAL;
3755 }
3756
Dino Mycle6fb96c12014-06-10 11:52:40 +05303757 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3758 data, dataLen,
3759 wlan_hdd_extscan_config_policy)) {
3760 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3761 return -EINVAL;
3762 }
3763 /* Parse and fetch request Id */
3764 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3765 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3766 return -EINVAL;
3767 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303768
Dino Myclee8843b32014-07-04 14:21:45 +05303769 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303770 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3771
Dino Myclee8843b32014-07-04 14:21:45 +05303772 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303773
Dino Myclee8843b32014-07-04 14:21:45 +05303774 reqMsg.sessionId = pAdapter->sessionId;
3775 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303776
3777 /* Parse and fetch flush parameter */
3778 if (!tb
3779 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3780 {
3781 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3782 goto failed;
3783 }
Dino Myclee8843b32014-07-04 14:21:45 +05303784 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303785 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3786
Dino Myclee8843b32014-07-04 14:21:45 +05303787 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303788
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303789 spin_lock(&hdd_context_lock);
3790 context = &pHddCtx->ext_scan_context;
3791 context->request_id = reqMsg.requestId;
3792 context->ignore_cached_results = false;
3793 INIT_COMPLETION(context->response_event);
3794 spin_unlock(&hdd_context_lock);
3795
Dino Myclee8843b32014-07-04 14:21:45 +05303796 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303797 if (!HAL_STATUS_SUCCESS(status)) {
3798 hddLog(VOS_TRACE_LEVEL_ERROR,
3799 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303800 return -EINVAL;
3801 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303802
3803 rc = wait_for_completion_timeout(&context->response_event,
3804 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3805 if (!rc) {
3806 hddLog(LOGE, FL("Target response timed out"));
3807 retval = -ETIMEDOUT;
3808 spin_lock(&hdd_context_lock);
3809 context->ignore_cached_results = true;
3810 spin_unlock(&hdd_context_lock);
3811 } else {
3812 spin_lock(&hdd_context_lock);
3813 retval = context->response_status;
3814 spin_unlock(&hdd_context_lock);
3815 }
3816
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303817 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303818 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303819
3820failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303821 return -EINVAL;
3822}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303823static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3824 struct wireless_dev *wdev,
3825 const void *data, int dataLen)
3826{
3827 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303828
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303829 vos_ssr_protect(__func__);
3830 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3831 vos_ssr_unprotect(__func__);
3832
3833 return ret;
3834}
3835
3836static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303837 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303838 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303839{
3840 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3841 struct net_device *dev = wdev->netdev;
3842 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3843 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3844 struct nlattr
3845 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3846 struct nlattr
3847 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3848 struct nlattr *apTh;
3849 eHalStatus status;
3850 tANI_U8 i = 0;
3851 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303852 struct hdd_ext_scan_context *context;
3853 tANI_U32 request_id;
3854 unsigned long rc;
3855 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303856
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303857 ENTER();
3858
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303859 if (VOS_FTM_MODE == hdd_get_conparam()) {
3860 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3861 return -EINVAL;
3862 }
3863
Dino Mycle6fb96c12014-06-10 11:52:40 +05303864 status = wlan_hdd_validate_context(pHddCtx);
3865 if (0 != status)
3866 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303867 return -EINVAL;
3868 }
Dino Myclee8843b32014-07-04 14:21:45 +05303869 /* check the EXTScan Capability */
3870 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3871 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3872 {
3873 hddLog(VOS_TRACE_LEVEL_ERROR,
3874 FL("EXTScan not enabled/supported by Firmware"));
3875 return -EINVAL;
3876 }
3877
Dino Mycle6fb96c12014-06-10 11:52:40 +05303878 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3879 data, dataLen,
3880 wlan_hdd_extscan_config_policy)) {
3881 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3882 return -EINVAL;
3883 }
3884
3885 /* Parse and fetch request Id */
3886 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3887 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3888 return -EINVAL;
3889 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303890 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3891 vos_mem_malloc(sizeof(*pReqMsg));
3892 if (!pReqMsg) {
3893 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3894 return -ENOMEM;
3895 }
3896
Dino Myclee8843b32014-07-04 14:21:45 +05303897
Dino Mycle6fb96c12014-06-10 11:52:40 +05303898 pReqMsg->requestId = nla_get_u32(
3899 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3900 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3901
3902 /* Parse and fetch number of APs */
3903 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3904 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3905 goto fail;
3906 }
3907
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303908 /* Parse and fetch lost ap sample size */
3909 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3910 hddLog(LOGE, FL("attr lost ap sample size failed"));
3911 goto fail;
3912 }
3913
3914 pReqMsg->lostBssidSampleSize = nla_get_u32(
3915 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3916 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3917
Dino Mycle6fb96c12014-06-10 11:52:40 +05303918 pReqMsg->sessionId = pAdapter->sessionId;
3919 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3920
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303921 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303922 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303923 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303924
3925 nla_for_each_nested(apTh,
3926 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3927 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3928 nla_data(apTh), nla_len(apTh),
3929 NULL)) {
3930 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3931 goto fail;
3932 }
3933
3934 /* Parse and fetch MAC address */
3935 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3936 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3937 goto fail;
3938 }
3939 memcpy(pReqMsg->ap[i].bssid, nla_data(
3940 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3941 sizeof(tSirMacAddr));
3942 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3943
3944 /* Parse and fetch low RSSI */
3945 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3946 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3947 goto fail;
3948 }
3949 pReqMsg->ap[i].low = nla_get_s32(
3950 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3951 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3952
3953 /* Parse and fetch high RSSI */
3954 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3955 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3956 goto fail;
3957 }
3958 pReqMsg->ap[i].high = nla_get_s32(
3959 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3960 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3961 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303962 i++;
3963 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303964
3965 context = &pHddCtx->ext_scan_context;
3966 spin_lock(&hdd_context_lock);
3967 INIT_COMPLETION(context->response_event);
3968 context->request_id = request_id = pReqMsg->requestId;
3969 spin_unlock(&hdd_context_lock);
3970
Dino Mycle6fb96c12014-06-10 11:52:40 +05303971 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3972 if (!HAL_STATUS_SUCCESS(status)) {
3973 hddLog(VOS_TRACE_LEVEL_ERROR,
3974 FL("sme_SetBssHotlist failed(err=%d)"), status);
3975 vos_mem_free(pReqMsg);
3976 return -EINVAL;
3977 }
3978
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303979 /* request was sent -- wait for the response */
3980 rc = wait_for_completion_timeout(&context->response_event,
3981 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3982
3983 if (!rc) {
3984 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3985 retval = -ETIMEDOUT;
3986 } else {
3987 spin_lock(&hdd_context_lock);
3988 if (context->request_id == request_id)
3989 retval = context->response_status;
3990 else
3991 retval = -EINVAL;
3992 spin_unlock(&hdd_context_lock);
3993 }
3994
Dino Myclee8843b32014-07-04 14:21:45 +05303995 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303996 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303997 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303998
3999fail:
4000 vos_mem_free(pReqMsg);
4001 return -EINVAL;
4002}
4003
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304004static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
4005 struct wireless_dev *wdev,
4006 const void *data, int dataLen)
4007{
4008 int ret = 0;
4009
4010 vos_ssr_protect(__func__);
4011 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
4012 dataLen);
4013 vos_ssr_unprotect(__func__);
4014
4015 return ret;
4016}
4017
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05304018/*
4019 * define short names for the global vendor params
4020 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4021 */
4022#define PARAM_MAX \
4023QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4024#define PARAM_REQUEST_ID \
4025QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4026#define PARAMS_LOST_SSID_SAMPLE_SIZE \
4027QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE
4028#define PARAMS_NUM_SSID \
4029QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID
4030#define THRESHOLD_PARAM \
4031QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM
4032#define PARAM_SSID \
4033QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID
4034#define PARAM_BAND \
4035QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND
4036#define PARAM_RSSI_LOW \
4037QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW
4038#define PARAM_RSSI_HIGH \
4039QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH
4040
4041/**
4042 * __wlan_hdd_cfg80211_extscan_set_ssid_hotlist() - set ssid hot list
4043 * @wiphy: Pointer to wireless phy
4044 * @wdev: Pointer to wireless device
4045 * @data: Pointer to data
4046 * @data_len: Data length
4047 *
4048 * Return: 0 on success, negative errno on failure
4049 */
4050static int
4051__wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4052 struct wireless_dev *wdev,
4053 const void *data,
4054 int data_len)
4055{
4056 tSirEXTScanSetSsidHotListReqParams *request;
4057 struct net_device *dev = wdev->netdev;
4058 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4059 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4060 struct nlattr *tb[PARAM_MAX + 1];
4061 struct nlattr *tb2[PARAM_MAX + 1];
4062 struct nlattr *ssids;
4063 struct hdd_ext_scan_context *context;
4064 uint32_t request_id;
4065 char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1] = {'\0'};
4066 int ssid_len;
4067 eHalStatus status;
4068 int i, rem, retval;
4069 unsigned long rc;
4070
4071 ENTER();
4072
4073 if (VOS_FTM_MODE == hdd_get_conparam()) {
4074 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4075 return -EINVAL;
4076 }
4077
4078 retval = wlan_hdd_validate_context(hdd_ctx);
4079 if (0 != retval) {
4080 hddLog(LOGE, FL("HDD context is not valid"));
4081 return -EINVAL;
4082 }
4083
4084 /* check the EXTScan Capability */
4085 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
4086 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4087 {
4088 hddLog(VOS_TRACE_LEVEL_ERROR,
4089 FL("EXTScan not enabled/supported by Firmware"));
4090 return -EINVAL;
4091 }
4092
4093 if (nla_parse(tb, PARAM_MAX,
4094 data, data_len,
4095 wlan_hdd_extscan_config_policy)) {
4096 hddLog(LOGE, FL("Invalid ATTR"));
4097 return -EINVAL;
4098 }
4099
4100 request = vos_mem_malloc(sizeof(*request));
4101 if (!request) {
4102 hddLog(LOGE, FL("vos_mem_malloc failed"));
4103 return -ENOMEM;
4104 }
4105
4106 /* Parse and fetch request Id */
4107 if (!tb[PARAM_REQUEST_ID]) {
4108 hddLog(LOGE, FL("attr request id failed"));
4109 goto fail;
4110 }
4111
4112 request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
4113 hddLog(LOG1, FL("Request Id %d"), request->request_id);
4114
4115 /* Parse and fetch lost SSID sample size */
4116 if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
4117 hddLog(LOGE, FL("attr number of Ssid failed"));
4118 goto fail;
4119 }
4120 request->lost_ssid_sample_size =
4121 nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
4122 hddLog(LOG1, FL("Lost SSID Sample Size %d"),
4123 request->lost_ssid_sample_size);
4124
4125 /* Parse and fetch number of hotlist SSID */
4126 if (!tb[PARAMS_NUM_SSID]) {
4127 hddLog(LOGE, FL("attr number of Ssid failed"));
4128 goto fail;
4129 }
4130 request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
4131 hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
4132
4133 request->session_id = adapter->sessionId;
4134 hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
4135
4136 i = 0;
4137 nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
4138 if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
4139 hddLog(LOGE,
4140 FL("Too Many SSIDs, %d exceeds %d"),
4141 i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
4142 break;
4143 }
4144 if (nla_parse(tb2, PARAM_MAX,
4145 nla_data(ssids), nla_len(ssids),
4146 wlan_hdd_extscan_config_policy)) {
4147 hddLog(LOGE, FL("nla_parse failed"));
4148 goto fail;
4149 }
4150
4151 /* Parse and fetch SSID */
4152 if (!tb2[PARAM_SSID]) {
4153 hddLog(LOGE, FL("attr ssid failed"));
4154 goto fail;
4155 }
4156 nla_memcpy(ssid_string,
4157 tb2[PARAM_SSID],
4158 sizeof(ssid_string));
4159 hddLog(LOG1, FL("SSID %s"),
4160 ssid_string);
4161 ssid_len = strlen(ssid_string);
4162 memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
4163 request->ssid[i].ssid.length = ssid_len;
4164 request->ssid[i].ssid.ssId[ssid_len] = '\0';
4165 hddLog(LOG1, FL("After copying SSID %s"),
4166 request->ssid[i].ssid.ssId);
4167 hddLog(LOG1, FL("After copying length: %d"),
4168 ssid_len);
4169
4170 /* Parse and fetch low RSSI */
4171 if (!tb2[PARAM_BAND]) {
4172 hddLog(LOGE, FL("attr band failed"));
4173 goto fail;
4174 }
4175 request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
4176 hddLog(LOG1, FL("band %d"), request->ssid[i].band);
4177
4178 /* Parse and fetch low RSSI */
4179 if (!tb2[PARAM_RSSI_LOW]) {
4180 hddLog(LOGE, FL("attr low RSSI failed"));
4181 goto fail;
4182 }
4183 request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
4184 hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
4185
4186 /* Parse and fetch high RSSI */
4187 if (!tb2[PARAM_RSSI_HIGH]) {
4188 hddLog(LOGE, FL("attr high RSSI failed"));
4189 goto fail;
4190 }
4191 request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
4192 hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
4193 i++;
4194 }
4195
4196 context = &hdd_ctx->ext_scan_context;
4197 spin_lock(&hdd_context_lock);
4198 INIT_COMPLETION(context->response_event);
4199 context->request_id = request_id = request->request_id;
4200 spin_unlock(&hdd_context_lock);
4201
4202 status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
4203 if (!HAL_STATUS_SUCCESS(status)) {
4204 hddLog(LOGE,
4205 FL("sme_set_ssid_hotlist failed(err=%d)"), status);
4206 goto fail;
4207 }
4208
4209 vos_mem_free(request);
4210
4211 /* request was sent -- wait for the response */
4212 rc = wait_for_completion_timeout(&context->response_event,
4213 msecs_to_jiffies
4214 (WLAN_WAIT_TIME_EXTSCAN));
4215 if (!rc) {
4216 hddLog(LOGE, FL("sme_set_ssid_hotlist timed out"));
4217 retval = -ETIMEDOUT;
4218 } else {
4219 spin_lock(&hdd_context_lock);
4220 if (context->request_id == request_id)
4221 retval = context->response_status;
4222 else
4223 retval = -EINVAL;
4224 spin_unlock(&hdd_context_lock);
4225 }
4226
4227 return retval;
4228
4229fail:
4230 vos_mem_free(request);
4231 return -EINVAL;
4232}
4233
4234/*
4235 * done with short names for the global vendor params
4236 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4237 */
4238#undef PARAM_MAX
4239#undef PARAM_REQUEST_ID
4240#undef PARAMS_NUM_SSID
4241#undef THRESHOLD_PARAM
4242#undef PARAM_SSID
4243#undef PARAM_BAND
4244#undef PARAM_RSSI_LOW
4245#undef PARAM_RSSI_HIGH
4246
4247static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4248 struct wireless_dev *wdev,
4249 const void *data, int dataLen)
4250{
4251 int ret = 0;
4252
4253 vos_ssr_protect(__func__);
4254 ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
4255 dataLen);
4256 vos_ssr_unprotect(__func__);
4257
4258 return ret;
4259}
4260
4261static int
4262__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4263 struct wireless_dev *wdev,
4264 const void *data,
4265 int data_len)
4266{
4267 tSirEXTScanResetSsidHotlistReqParams request;
4268 struct net_device *dev = wdev->netdev;
4269 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4270 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4271 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4272 struct hdd_ext_scan_context *context;
4273 uint32_t request_id;
4274 eHalStatus status;
4275 int retval;
4276 unsigned long rc;
4277
4278 ENTER();
4279
4280 if (VOS_FTM_MODE == hdd_get_conparam()) {
4281 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4282 return -EINVAL;
4283 }
4284
4285 retval = wlan_hdd_validate_context(hdd_ctx);
4286 if (0 != retval) {
4287 hddLog(LOGE, FL("HDD context is not valid"));
4288 return -EINVAL;
4289 }
4290
4291 /* check the EXTScan Capability */
4292 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
4293 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4294 {
4295 hddLog(LOGE,
4296 FL("EXTScan not enabled/supported by Firmware"));
4297 return -EINVAL;
4298 }
4299
4300 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4301 data, data_len,
4302 wlan_hdd_extscan_config_policy)) {
4303 hddLog(LOGE, FL("Invalid ATTR"));
4304 return -EINVAL;
4305 }
4306
4307 /* Parse and fetch request Id */
4308 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4309 hddLog(LOGE, FL("attr request id failed"));
4310 return -EINVAL;
4311 }
4312
4313 request.requestId = nla_get_u32(
4314 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4315 request.sessionId = adapter->sessionId;
4316 hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
4317 request.sessionId);
4318
4319 context = &hdd_ctx->ext_scan_context;
4320 spin_lock(&hdd_context_lock);
4321 INIT_COMPLETION(context->response_event);
4322 context->request_id = request_id = request.requestId;
4323 spin_unlock(&hdd_context_lock);
4324
4325 status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
4326 if (!HAL_STATUS_SUCCESS(status)) {
4327 hddLog(LOGE,
4328 FL("sme_reset_ssid_hotlist failed(err=%d)"), status);
4329 return -EINVAL;
4330 }
4331
4332 /* request was sent -- wait for the response */
4333 rc = wait_for_completion_timeout(&context->response_event,
4334 msecs_to_jiffies
4335 (WLAN_WAIT_TIME_EXTSCAN));
4336 if (!rc) {
4337 hddLog(LOGE, FL("sme_reset_ssid_hotlist timed out"));
4338 retval = -ETIMEDOUT;
4339 } else {
4340 spin_lock(&hdd_context_lock);
4341 if (context->request_id == request_id)
4342 retval = context->response_status;
4343 else
4344 retval = -EINVAL;
4345 spin_unlock(&hdd_context_lock);
4346 }
4347
4348 return retval;
4349}
4350
4351static int
4352wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4353 struct wireless_dev *wdev,
4354 const void *data,
4355 int data_len)
4356{
4357 int ret;
4358
4359 vos_ssr_protect(__func__);
4360 ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
4361 data, data_len);
4362 vos_ssr_unprotect(__func__);
4363
4364 return ret;
4365}
4366
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304367static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304368 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304369 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304370{
4371 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4372 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4373 tANI_U8 numChannels = 0;
4374 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304375 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304376 tWifiBand wifiBand;
4377 eHalStatus status;
4378 struct sk_buff *replySkb;
4379 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304380 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304381
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304382 ENTER();
4383
Dino Mycle6fb96c12014-06-10 11:52:40 +05304384 status = wlan_hdd_validate_context(pHddCtx);
4385 if (0 != status)
4386 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304387 return -EINVAL;
4388 }
Dino Myclee8843b32014-07-04 14:21:45 +05304389
Dino Mycle6fb96c12014-06-10 11:52:40 +05304390 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4391 data, dataLen,
4392 wlan_hdd_extscan_config_policy)) {
4393 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4394 return -EINVAL;
4395 }
4396
4397 /* Parse and fetch request Id */
4398 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4399 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4400 return -EINVAL;
4401 }
4402 requestId = nla_get_u32(
4403 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4404 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4405
4406 /* Parse and fetch wifi band */
4407 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4408 {
4409 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4410 return -EINVAL;
4411 }
4412 wifiBand = nla_get_u32(
4413 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4414 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4415
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304416 /* Parse and fetch max channels */
4417 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4418 {
4419 hddLog(LOGE, FL("attr max channels failed"));
4420 return -EINVAL;
4421 }
4422 maxChannels = nla_get_u32(
4423 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4424 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4425
Dino Mycle6fb96c12014-06-10 11:52:40 +05304426 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
4427 wifiBand, ChannelList,
4428 &numChannels);
4429 if (eHAL_STATUS_SUCCESS != status) {
4430 hddLog(VOS_TRACE_LEVEL_ERROR,
4431 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4432 return -EINVAL;
4433 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304434
4435 numChannels = VOS_MIN(numChannels, maxChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304436 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304437
Dino Mycle6fb96c12014-06-10 11:52:40 +05304438 for (i = 0; i < numChannels; i++)
4439 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
4440
4441 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4442 sizeof(u32) * numChannels +
4443 NLMSG_HDRLEN);
4444
4445 if (!replySkb) {
4446 hddLog(VOS_TRACE_LEVEL_ERROR,
4447 FL("valid channels: buffer alloc fail"));
4448 return -EINVAL;
4449 }
4450 if (nla_put_u32(replySkb,
4451 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
4452 numChannels) ||
4453 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
4454 sizeof(u32) * numChannels, ChannelList)) {
4455
4456 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4457 kfree_skb(replySkb);
4458 return -EINVAL;
4459 }
4460
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304461 ret = cfg80211_vendor_cmd_reply(replySkb);
4462
4463 EXIT();
4464 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304465}
4466
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304467static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4468 struct wireless_dev *wdev,
4469 const void *data, int dataLen)
4470{
4471 int ret = 0;
4472
4473 vos_ssr_protect(__func__);
4474 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4475 dataLen);
4476 vos_ssr_unprotect(__func__);
4477
4478 return ret;
4479}
4480
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304481static int hdd_extscan_start_fill_bucket_channel_spec(
4482 hdd_context_t *pHddCtx,
4483 tpSirEXTScanStartReqParams pReqMsg,
4484 struct nlattr **tb)
4485{
4486 struct nlattr *bucket[
4487 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4488 struct nlattr *channel[
4489 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4490 struct nlattr *buckets;
4491 struct nlattr *channels;
4492 int rem1, rem2;
4493 eHalStatus status;
4494 tANI_U8 bktIndex, j, numChannels;
4495 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4496 tANI_U32 passive_max_chn_time, active_max_chn_time;
4497
4498 bktIndex = 0;
4499
4500 nla_for_each_nested(buckets,
4501 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4502 if (nla_parse(bucket,
4503 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4504 nla_data(buckets), nla_len(buckets), NULL)) {
4505 hddLog(LOGE, FL("nla_parse failed"));
4506 return -EINVAL;
4507 }
4508
4509 /* Parse and fetch bucket spec */
4510 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4511 hddLog(LOGE, FL("attr bucket index failed"));
4512 return -EINVAL;
4513 }
4514 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4515 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4516 hddLog(LOG1, FL("Bucket spec Index %d"),
4517 pReqMsg->buckets[bktIndex].bucket);
4518
4519 /* Parse and fetch wifi band */
4520 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4521 hddLog(LOGE, FL("attr wifi band failed"));
4522 return -EINVAL;
4523 }
4524 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4525 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4526 hddLog(LOG1, FL("Wifi band %d"),
4527 pReqMsg->buckets[bktIndex].band);
4528
4529 /* Parse and fetch period */
4530 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4531 hddLog(LOGE, FL("attr period failed"));
4532 return -EINVAL;
4533 }
4534 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4535 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4536 hddLog(LOG1, FL("period %d"),
4537 pReqMsg->buckets[bktIndex].period);
4538
4539 /* Parse and fetch report events */
4540 if (!bucket[
4541 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4542 hddLog(LOGE, FL("attr report events failed"));
4543 return -EINVAL;
4544 }
4545 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4546 bucket[
4547 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4548 hddLog(LOG1, FL("report events %d"),
4549 pReqMsg->buckets[bktIndex].reportEvents);
4550
4551 /* Parse and fetch max period */
4552 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4553 hddLog(LOGE, FL("attr max period failed"));
4554 return -EINVAL;
4555 }
4556 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4557 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4558 hddLog(LOG1, FL("max period %u"),
4559 pReqMsg->buckets[bktIndex].max_period);
4560
4561 /* Parse and fetch exponent */
4562 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4563 hddLog(LOGE, FL("attr exponent failed"));
4564 return -EINVAL;
4565 }
4566 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4567 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4568 hddLog(LOG1, FL("exponent %u"),
4569 pReqMsg->buckets[bktIndex].exponent);
4570
4571 /* Parse and fetch step count */
4572 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4573 hddLog(LOGE, FL("attr step count failed"));
4574 return -EINVAL;
4575 }
4576 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4577 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4578 hddLog(LOG1, FL("Step count %u"),
4579 pReqMsg->buckets[bktIndex].step_count);
4580
4581 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4582 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4583
4584 /* Framework shall pass the channel list if the input WiFi band is
4585 * WIFI_BAND_UNSPECIFIED.
4586 * If the input WiFi band is specified (any value other than
4587 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4588 */
4589 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4590 numChannels = 0;
4591 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4592 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4593 pReqMsg->buckets[bktIndex].band,
4594 chanList, &numChannels);
4595 if (!HAL_STATUS_SUCCESS(status)) {
4596 hddLog(LOGE,
4597 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4598 status);
4599 return -EINVAL;
4600 }
4601
4602 pReqMsg->buckets[bktIndex].numChannels =
4603 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4604 hddLog(LOG1, FL("Num channels %d"),
4605 pReqMsg->buckets[bktIndex].numChannels);
4606
4607 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4608 j++) {
4609 pReqMsg->buckets[bktIndex].channels[j].channel =
4610 chanList[j];
4611 pReqMsg->buckets[bktIndex].channels[j].
4612 chnlClass = 0;
4613 if (CSR_IS_CHANNEL_DFS(
4614 vos_freq_to_chan(chanList[j]))) {
4615 pReqMsg->buckets[bktIndex].channels[j].
4616 passive = 1;
4617 pReqMsg->buckets[bktIndex].channels[j].
4618 dwellTimeMs = passive_max_chn_time;
4619 } else {
4620 pReqMsg->buckets[bktIndex].channels[j].
4621 passive = 0;
4622 pReqMsg->buckets[bktIndex].channels[j].
4623 dwellTimeMs = active_max_chn_time;
4624 }
4625
4626 hddLog(LOG1,
4627 "Channel %u Passive %u Dwell time %u ms",
4628 pReqMsg->buckets[bktIndex].channels[j].channel,
4629 pReqMsg->buckets[bktIndex].channels[j].passive,
4630 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4631 }
4632
4633 bktIndex++;
4634 continue;
4635 }
4636
4637 /* Parse and fetch number of channels */
4638 if (!bucket[
4639 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4640 hddLog(LOGE, FL("attr num channels failed"));
4641 return -EINVAL;
4642 }
4643
4644 pReqMsg->buckets[bktIndex].numChannels =
4645 nla_get_u32(bucket[
4646 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4647 hddLog(LOG1, FL("num channels %d"),
4648 pReqMsg->buckets[bktIndex].numChannels);
4649
4650 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4651 hddLog(LOGE, FL("attr channel spec failed"));
4652 return -EINVAL;
4653 }
4654
4655 j = 0;
4656 nla_for_each_nested(channels,
4657 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4658 if (nla_parse(channel,
4659 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4660 nla_data(channels), nla_len(channels),
4661 wlan_hdd_extscan_config_policy)) {
4662 hddLog(LOGE, FL("nla_parse failed"));
4663 return -EINVAL;
4664 }
4665
4666 /* Parse and fetch channel */
4667 if (!channel[
4668 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4669 hddLog(LOGE, FL("attr channel failed"));
4670 return -EINVAL;
4671 }
4672 pReqMsg->buckets[bktIndex].channels[j].channel =
4673 nla_get_u32(channel[
4674 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4675 hddLog(LOG1, FL("channel %u"),
4676 pReqMsg->buckets[bktIndex].channels[j].channel);
4677
4678 /* Parse and fetch dwell time */
4679 if (!channel[
4680 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4681 hddLog(LOGE, FL("attr dwelltime failed"));
4682 return -EINVAL;
4683 }
4684 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4685 nla_get_u32(channel[
4686 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4687
4688 hddLog(LOG1, FL("Dwell time (%u ms)"),
4689 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4690
4691
4692 /* Parse and fetch channel spec passive */
4693 if (!channel[
4694 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4695 hddLog(LOGE,
4696 FL("attr channel spec passive failed"));
4697 return -EINVAL;
4698 }
4699 pReqMsg->buckets[bktIndex].channels[j].passive =
4700 nla_get_u8(channel[
4701 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4702 hddLog(LOG1, FL("Chnl spec passive %u"),
4703 pReqMsg->buckets[bktIndex].channels[j].passive);
4704
4705 j++;
4706 }
4707
4708 bktIndex++;
4709 }
4710
4711 return 0;
4712}
4713
4714
4715/*
4716 * define short names for the global vendor params
4717 * used by wlan_hdd_cfg80211_extscan_start()
4718 */
4719#define PARAM_MAX \
4720QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4721#define PARAM_REQUEST_ID \
4722QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4723#define PARAM_BASE_PERIOD \
4724QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4725#define PARAM_MAX_AP_PER_SCAN \
4726QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4727#define PARAM_RPT_THRHLD_PERCENT \
4728QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4729#define PARAM_RPT_THRHLD_NUM_SCANS \
4730QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4731#define PARAM_NUM_BUCKETS \
4732QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4733
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304734static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304735 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304736 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304737{
Dino Myclee8843b32014-07-04 14:21:45 +05304738 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304739 struct net_device *dev = wdev->netdev;
4740 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4741 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4742 struct nlattr *tb[PARAM_MAX + 1];
4743 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304744 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304745 tANI_U32 request_id;
4746 struct hdd_ext_scan_context *context;
4747 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304748
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304749 ENTER();
4750
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304751 if (VOS_FTM_MODE == hdd_get_conparam()) {
4752 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4753 return -EINVAL;
4754 }
4755
Dino Mycle6fb96c12014-06-10 11:52:40 +05304756 status = wlan_hdd_validate_context(pHddCtx);
4757 if (0 != status)
4758 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304759 return -EINVAL;
4760 }
Dino Myclee8843b32014-07-04 14:21:45 +05304761 /* check the EXTScan Capability */
4762 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4763 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4764 {
4765 hddLog(VOS_TRACE_LEVEL_ERROR,
4766 FL("EXTScan not enabled/supported by Firmware"));
4767 return -EINVAL;
4768 }
4769
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304770 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304771 data, dataLen,
4772 wlan_hdd_extscan_config_policy)) {
4773 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4774 return -EINVAL;
4775 }
4776
4777 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304778 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304779 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4780 return -EINVAL;
4781 }
4782
Dino Myclee8843b32014-07-04 14:21:45 +05304783 pReqMsg = (tpSirEXTScanStartReqParams)
4784 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304785 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304786 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4787 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304788 }
4789
4790 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304791 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304792 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4793
4794 pReqMsg->sessionId = pAdapter->sessionId;
4795 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4796
4797 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304798 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304799 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4800 goto fail;
4801 }
4802 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304803 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304804 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4805 pReqMsg->basePeriod);
4806
4807 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304808 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304809 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4810 goto fail;
4811 }
4812 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304813 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304814 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4815 pReqMsg->maxAPperScan);
4816
4817 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304818 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304819 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4820 goto fail;
4821 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304822 pReqMsg->reportThresholdPercent = nla_get_u8(
4823 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304824 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304825 pReqMsg->reportThresholdPercent);
4826
4827 /* Parse and fetch report threshold num scans */
4828 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4829 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4830 goto fail;
4831 }
4832 pReqMsg->reportThresholdNumScans = nla_get_u8(
4833 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4834 hddLog(LOG1, FL("Report Threshold num scans %d"),
4835 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304836
4837 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304838 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304839 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4840 goto fail;
4841 }
4842 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304843 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304844 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4845 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4846 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4847 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4848 }
4849 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4850 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304851
Dino Mycle6fb96c12014-06-10 11:52:40 +05304852 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4853 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4854 goto fail;
4855 }
4856
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304857 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304858
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304859 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4860 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304861
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304862 context = &pHddCtx->ext_scan_context;
4863 spin_lock(&hdd_context_lock);
4864 INIT_COMPLETION(context->response_event);
4865 context->request_id = request_id = pReqMsg->requestId;
4866 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304867
Dino Mycle6fb96c12014-06-10 11:52:40 +05304868 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4869 if (!HAL_STATUS_SUCCESS(status)) {
4870 hddLog(VOS_TRACE_LEVEL_ERROR,
4871 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304872 goto fail;
4873 }
4874
4875 /* request was sent -- wait for the response */
4876 rc = wait_for_completion_timeout(&context->response_event,
4877 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4878
4879 if (!rc) {
4880 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4881 retval = -ETIMEDOUT;
4882 } else {
4883 spin_lock(&hdd_context_lock);
4884 if (context->request_id == request_id)
4885 retval = context->response_status;
4886 else
4887 retval = -EINVAL;
4888 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304889 }
4890
Dino Myclee8843b32014-07-04 14:21:45 +05304891 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304892 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304893 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304894
4895fail:
4896 vos_mem_free(pReqMsg);
4897 return -EINVAL;
4898}
4899
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304900/*
4901 * done with short names for the global vendor params
4902 * used by wlan_hdd_cfg80211_extscan_start()
4903 */
4904#undef PARAM_MAX
4905#undef PARAM_REQUEST_ID
4906#undef PARAM_BASE_PERIOD
4907#undef PARAMS_MAX_AP_PER_SCAN
4908#undef PARAMS_RPT_THRHLD_PERCENT
4909#undef PARAMS_RPT_THRHLD_NUM_SCANS
4910#undef PARAMS_NUM_BUCKETS
4911
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304912static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4913 struct wireless_dev *wdev,
4914 const void *data, int dataLen)
4915{
4916 int ret = 0;
4917
4918 vos_ssr_protect(__func__);
4919 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4920 vos_ssr_unprotect(__func__);
4921
4922 return ret;
4923}
4924
4925static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304926 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304927 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304928{
Dino Myclee8843b32014-07-04 14:21:45 +05304929 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304930 struct net_device *dev = wdev->netdev;
4931 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4932 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4933 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4934 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304935 int retval;
4936 unsigned long rc;
4937 struct hdd_ext_scan_context *context;
4938 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304939
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304940 ENTER();
4941
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304942 if (VOS_FTM_MODE == hdd_get_conparam()) {
4943 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4944 return -EINVAL;
4945 }
4946
Dino Mycle6fb96c12014-06-10 11:52:40 +05304947 status = wlan_hdd_validate_context(pHddCtx);
4948 if (0 != status)
4949 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304950 return -EINVAL;
4951 }
Dino Myclee8843b32014-07-04 14:21:45 +05304952 /* check the EXTScan Capability */
4953 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4954 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4955 {
4956 hddLog(VOS_TRACE_LEVEL_ERROR,
4957 FL("EXTScan not enabled/supported by Firmware"));
4958 return -EINVAL;
4959 }
4960
Dino Mycle6fb96c12014-06-10 11:52:40 +05304961 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4962 data, dataLen,
4963 wlan_hdd_extscan_config_policy)) {
4964 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4965 return -EINVAL;
4966 }
4967
4968 /* Parse and fetch request Id */
4969 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4970 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4971 return -EINVAL;
4972 }
4973
Dino Myclee8843b32014-07-04 14:21:45 +05304974 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304975 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304976 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304977
Dino Myclee8843b32014-07-04 14:21:45 +05304978 reqMsg.sessionId = pAdapter->sessionId;
4979 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304980
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304981 context = &pHddCtx->ext_scan_context;
4982 spin_lock(&hdd_context_lock);
4983 INIT_COMPLETION(context->response_event);
4984 context->request_id = request_id = reqMsg.sessionId;
4985 spin_unlock(&hdd_context_lock);
4986
Dino Myclee8843b32014-07-04 14:21:45 +05304987 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304988 if (!HAL_STATUS_SUCCESS(status)) {
4989 hddLog(VOS_TRACE_LEVEL_ERROR,
4990 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304991 return -EINVAL;
4992 }
4993
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304994 /* request was sent -- wait for the response */
4995 rc = wait_for_completion_timeout(&context->response_event,
4996 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4997
4998 if (!rc) {
4999 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
5000 retval = -ETIMEDOUT;
5001 } else {
5002 spin_lock(&hdd_context_lock);
5003 if (context->request_id == request_id)
5004 retval = context->response_status;
5005 else
5006 retval = -EINVAL;
5007 spin_unlock(&hdd_context_lock);
5008 }
5009
5010 return retval;
5011
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305012 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05305013 return 0;
5014}
5015
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305016static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
5017 struct wireless_dev *wdev,
5018 const void *data, int dataLen)
5019{
5020 int ret = 0;
5021
5022 vos_ssr_protect(__func__);
5023 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
5024 vos_ssr_unprotect(__func__);
5025
5026 return ret;
5027}
5028
5029static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05305030 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305031 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05305032{
Dino Myclee8843b32014-07-04 14:21:45 +05305033 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305034 struct net_device *dev = wdev->netdev;
5035 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5036 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5037 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
5038 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305039 struct hdd_ext_scan_context *context;
5040 tANI_U32 request_id;
5041 unsigned long rc;
5042 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305043
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305044 ENTER();
5045
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305046 if (VOS_FTM_MODE == hdd_get_conparam()) {
5047 hddLog(LOGE, FL("Command not allowed in FTM mode"));
5048 return -EINVAL;
5049 }
5050
Dino Mycle6fb96c12014-06-10 11:52:40 +05305051 status = wlan_hdd_validate_context(pHddCtx);
5052 if (0 != status)
5053 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305054 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05305055 return -EINVAL;
5056 }
Dino Myclee8843b32014-07-04 14:21:45 +05305057 /* check the EXTScan Capability */
5058 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
5059 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
5060 {
5061 hddLog(VOS_TRACE_LEVEL_ERROR,
5062 FL("EXTScan not enabled/supported by Firmware"));
5063 return -EINVAL;
5064 }
5065
Dino Mycle6fb96c12014-06-10 11:52:40 +05305066 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
5067 data, dataLen,
5068 wlan_hdd_extscan_config_policy)) {
5069 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5070 return -EINVAL;
5071 }
5072
5073 /* Parse and fetch request Id */
5074 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
5075 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
5076 return -EINVAL;
5077 }
5078
Dino Myclee8843b32014-07-04 14:21:45 +05305079 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05305080 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05305081 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305082
Dino Myclee8843b32014-07-04 14:21:45 +05305083 reqMsg.sessionId = pAdapter->sessionId;
5084 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305085
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305086 context = &pHddCtx->ext_scan_context;
5087 spin_lock(&hdd_context_lock);
5088 INIT_COMPLETION(context->response_event);
5089 context->request_id = request_id = reqMsg.requestId;
5090 spin_unlock(&hdd_context_lock);
5091
Dino Myclee8843b32014-07-04 14:21:45 +05305092 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305093 if (!HAL_STATUS_SUCCESS(status)) {
5094 hddLog(VOS_TRACE_LEVEL_ERROR,
5095 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05305096 return -EINVAL;
5097 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305098
5099 /* request was sent -- wait for the response */
5100 rc = wait_for_completion_timeout(&context->response_event,
5101 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
5102 if (!rc) {
5103 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
5104 retval = -ETIMEDOUT;
5105 } else {
5106 spin_lock(&hdd_context_lock);
5107 if (context->request_id == request_id)
5108 retval = context->response_status;
5109 else
5110 retval = -EINVAL;
5111 spin_unlock(&hdd_context_lock);
5112 }
5113
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305114 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05305115 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05305116}
5117
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305118static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
5119 struct wireless_dev *wdev,
5120 const void *data, int dataLen)
5121{
5122 int ret = 0;
5123
5124 vos_ssr_protect(__func__);
5125 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
5126 vos_ssr_unprotect(__func__);
5127
5128 return ret;
5129}
Dino Mycle6fb96c12014-06-10 11:52:40 +05305130#endif /* WLAN_FEATURE_EXTSCAN */
5131
Atul Mittal115287b2014-07-08 13:26:33 +05305132/*EXT TDLS*/
5133static const struct nla_policy
5134wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
5135{
5136 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
5137 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
5138 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
5139 {.type = NLA_S32 },
5140 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
5141 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
5142
5143};
5144
5145static const struct nla_policy
5146wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
5147{
5148 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
5149
5150};
5151
5152static const struct nla_policy
5153wlan_hdd_tdls_config_state_change_policy[
5154 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
5155{
5156 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
5157 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
5158 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305159 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
5160 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
5161 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305162
5163};
5164
5165static const struct nla_policy
5166wlan_hdd_tdls_config_get_status_policy[
5167 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
5168{
5169 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
5170 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
5171 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305172 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
5173 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
5174 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05305175
5176};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305177
5178static const struct nla_policy
5179wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
5180{
5181 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
5182};
5183
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305184static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305185 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305186 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305187 int data_len)
5188{
5189
5190 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5191 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5192
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305193 ENTER();
5194
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305195 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305196 return -EINVAL;
5197 }
5198 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305199 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305200 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305201 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305202 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305203 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305204 return -ENOTSUPP;
5205 }
5206
5207 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5208 data, data_len, wlan_hdd_mac_config)) {
5209 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5210 return -EINVAL;
5211 }
5212
5213 /* Parse and fetch mac address */
5214 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5215 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5216 return -EINVAL;
5217 }
5218
5219 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5220 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5221 VOS_MAC_ADDR_LAST_3_BYTES);
5222
Siddharth Bhal76972212014-10-15 16:22:51 +05305223 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5224
5225 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305226 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5227 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305228 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5229 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5230 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5231 {
5232 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5233 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5234 VOS_MAC_ADDRESS_LEN);
5235 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305236 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305237
Siddharth Bhal76972212014-10-15 16:22:51 +05305238 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
5239 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305240 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
5241 }
5242
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305243 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305244 return 0;
5245}
5246
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305247static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5248 struct wireless_dev *wdev,
5249 const void *data,
5250 int data_len)
5251{
5252 int ret = 0;
5253
5254 vos_ssr_protect(__func__);
5255 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5256 vos_ssr_unprotect(__func__);
5257
5258 return ret;
5259}
5260
5261static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305262 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305263 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305264 int data_len)
5265{
5266 u8 peer[6] = {0};
5267 struct net_device *dev = wdev->netdev;
5268 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5269 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5270 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5271 eHalStatus ret;
5272 tANI_S32 state;
5273 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305274 tANI_S32 global_operating_class = 0;
5275 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305276 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305277 int retVal;
5278
5279 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305280
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305281 if (!pAdapter) {
5282 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5283 return -EINVAL;
5284 }
5285
Atul Mittal115287b2014-07-08 13:26:33 +05305286 ret = wlan_hdd_validate_context(pHddCtx);
5287 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305288 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305289 return -EINVAL;
5290 }
5291 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305292 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305293 return -ENOTSUPP;
5294 }
5295 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5296 data, data_len,
5297 wlan_hdd_tdls_config_get_status_policy)) {
5298 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5299 return -EINVAL;
5300 }
5301
5302 /* Parse and fetch mac address */
5303 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5304 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5305 return -EINVAL;
5306 }
5307
5308 memcpy(peer, nla_data(
5309 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5310 sizeof(peer));
5311 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5312
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305313 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305314
Atul Mittal115287b2014-07-08 13:26:33 +05305315 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305316 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305317 NLMSG_HDRLEN);
5318
5319 if (!skb) {
5320 hddLog(VOS_TRACE_LEVEL_ERROR,
5321 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5322 return -EINVAL;
5323 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305324 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 +05305325 reason,
5326 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305327 global_operating_class,
5328 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305329 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305330 if (nla_put_s32(skb,
5331 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5332 state) ||
5333 nla_put_s32(skb,
5334 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5335 reason) ||
5336 nla_put_s32(skb,
5337 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5338 global_operating_class) ||
5339 nla_put_s32(skb,
5340 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5341 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305342
5343 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5344 goto nla_put_failure;
5345 }
5346
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305347 retVal = cfg80211_vendor_cmd_reply(skb);
5348 EXIT();
5349 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305350
5351nla_put_failure:
5352 kfree_skb(skb);
5353 return -EINVAL;
5354}
5355
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305356static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5357 struct wireless_dev *wdev,
5358 const void *data,
5359 int data_len)
5360{
5361 int ret = 0;
5362
5363 vos_ssr_protect(__func__);
5364 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5365 vos_ssr_unprotect(__func__);
5366
5367 return ret;
5368}
5369
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305370static int wlan_hdd_cfg80211_exttdls_callback(
5371#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5372 const tANI_U8* mac,
5373#else
5374 tANI_U8* mac,
5375#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305376 tANI_S32 state,
5377 tANI_S32 reason,
5378 void *ctx)
5379{
5380 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305381 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305382 tANI_S32 global_operating_class = 0;
5383 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305384 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305385
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305386 ENTER();
5387
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305388 if (!pAdapter) {
5389 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5390 return -EINVAL;
5391 }
5392
5393 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305394 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305395 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305396 return -EINVAL;
5397 }
5398
5399 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305400 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305401 return -ENOTSUPP;
5402 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305403 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5404#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5405 NULL,
5406#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305407 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5408 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5409 GFP_KERNEL);
5410
5411 if (!skb) {
5412 hddLog(VOS_TRACE_LEVEL_ERROR,
5413 FL("cfg80211_vendor_event_alloc failed"));
5414 return -EINVAL;
5415 }
5416 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305417 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5418 reason,
5419 state,
5420 global_operating_class,
5421 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305422 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5423 MAC_ADDR_ARRAY(mac));
5424
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305425 if (nla_put(skb,
5426 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5427 VOS_MAC_ADDR_SIZE, mac) ||
5428 nla_put_s32(skb,
5429 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5430 state) ||
5431 nla_put_s32(skb,
5432 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5433 reason) ||
5434 nla_put_s32(skb,
5435 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5436 channel) ||
5437 nla_put_s32(skb,
5438 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5439 global_operating_class)
5440 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305441 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5442 goto nla_put_failure;
5443 }
5444
5445 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305446 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305447 return (0);
5448
5449nla_put_failure:
5450 kfree_skb(skb);
5451 return -EINVAL;
5452}
5453
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305454static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305455 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305456 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305457 int data_len)
5458{
5459 u8 peer[6] = {0};
5460 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305461 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5462 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5463 eHalStatus status;
5464 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305465 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305466 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305467
5468 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305469
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305470 if (!dev) {
5471 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5472 return -EINVAL;
5473 }
5474
5475 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5476 if (!pAdapter) {
5477 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5478 return -EINVAL;
5479 }
5480
Atul Mittal115287b2014-07-08 13:26:33 +05305481 status = wlan_hdd_validate_context(pHddCtx);
5482 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305483 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305484 return -EINVAL;
5485 }
5486 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305487 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305488 return -ENOTSUPP;
5489 }
5490 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5491 data, data_len,
5492 wlan_hdd_tdls_config_enable_policy)) {
5493 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5494 return -EINVAL;
5495 }
5496
5497 /* Parse and fetch mac address */
5498 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5499 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5500 return -EINVAL;
5501 }
5502
5503 memcpy(peer, nla_data(
5504 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5505 sizeof(peer));
5506 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5507
5508 /* Parse and fetch channel */
5509 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5510 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5511 return -EINVAL;
5512 }
5513 pReqMsg.channel = nla_get_s32(
5514 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5515 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5516
5517 /* Parse and fetch global operating class */
5518 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5519 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5520 return -EINVAL;
5521 }
5522 pReqMsg.global_operating_class = nla_get_s32(
5523 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5524 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5525 pReqMsg.global_operating_class);
5526
5527 /* Parse and fetch latency ms */
5528 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5529 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5530 return -EINVAL;
5531 }
5532 pReqMsg.max_latency_ms = nla_get_s32(
5533 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5534 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5535 pReqMsg.max_latency_ms);
5536
5537 /* Parse and fetch required bandwidth kbps */
5538 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5539 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5540 return -EINVAL;
5541 }
5542
5543 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5544 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5545 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5546 pReqMsg.min_bandwidth_kbps);
5547
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305548 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305549 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305550 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305551 wlan_hdd_cfg80211_exttdls_callback);
5552
5553 EXIT();
5554 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305555}
5556
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305557static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5558 struct wireless_dev *wdev,
5559 const void *data,
5560 int data_len)
5561{
5562 int ret = 0;
5563
5564 vos_ssr_protect(__func__);
5565 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5566 vos_ssr_unprotect(__func__);
5567
5568 return ret;
5569}
5570
5571static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305572 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305573 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305574 int data_len)
5575{
5576 u8 peer[6] = {0};
5577 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305578 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5579 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5580 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305581 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305582 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305583
5584 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305585
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305586 if (!dev) {
5587 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5588 return -EINVAL;
5589 }
5590
5591 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5592 if (!pAdapter) {
5593 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5594 return -EINVAL;
5595 }
5596
Atul Mittal115287b2014-07-08 13:26:33 +05305597 status = wlan_hdd_validate_context(pHddCtx);
5598 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305599 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305600 return -EINVAL;
5601 }
5602 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305603 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305604 return -ENOTSUPP;
5605 }
5606 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5607 data, data_len,
5608 wlan_hdd_tdls_config_disable_policy)) {
5609 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5610 return -EINVAL;
5611 }
5612 /* Parse and fetch mac address */
5613 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5614 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5615 return -EINVAL;
5616 }
5617
5618 memcpy(peer, nla_data(
5619 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5620 sizeof(peer));
5621 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5622
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305623 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5624
5625 EXIT();
5626 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305627}
5628
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305629static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5630 struct wireless_dev *wdev,
5631 const void *data,
5632 int data_len)
5633{
5634 int ret = 0;
5635
5636 vos_ssr_protect(__func__);
5637 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5638 vos_ssr_unprotect(__func__);
5639
5640 return ret;
5641}
5642
Dasari Srinivas7875a302014-09-26 17:50:57 +05305643static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305644__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305645 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305646 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305647{
5648 struct net_device *dev = wdev->netdev;
5649 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5650 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5651 struct sk_buff *skb = NULL;
5652 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305653 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305654
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305655 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305656
5657 ret = wlan_hdd_validate_context(pHddCtx);
5658 if (0 != ret)
5659 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305660 return ret;
5661 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305662 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5663 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5664 fset |= WIFI_FEATURE_INFRA;
5665 }
5666
5667 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5668 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5669 fset |= WIFI_FEATURE_INFRA_5G;
5670 }
5671
5672#ifdef WLAN_FEATURE_P2P
5673 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5674 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5675 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5676 fset |= WIFI_FEATURE_P2P;
5677 }
5678#endif
5679
5680 /* Soft-AP is supported currently by default */
5681 fset |= WIFI_FEATURE_SOFT_AP;
5682
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305683 /* HOTSPOT is a supplicant feature, enable it by default */
5684 fset |= WIFI_FEATURE_HOTSPOT;
5685
Dasari Srinivas7875a302014-09-26 17:50:57 +05305686#ifdef WLAN_FEATURE_EXTSCAN
5687 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
5688 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
5689 hddLog(LOG1, FL("EXTScan is supported by firmware"));
5690 fset |= WIFI_FEATURE_EXTSCAN;
5691 }
5692#endif
5693
Dasari Srinivas7875a302014-09-26 17:50:57 +05305694 if (sme_IsFeatureSupportedByFW(NAN)) {
5695 hddLog(LOG1, FL("NAN is supported by firmware"));
5696 fset |= WIFI_FEATURE_NAN;
5697 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305698
5699 /* D2D RTT is not supported currently by default */
5700 if (sme_IsFeatureSupportedByFW(RTT)) {
5701 hddLog(LOG1, FL("RTT is supported by firmware"));
5702 fset |= WIFI_FEATURE_D2AP_RTT;
5703 }
5704
5705#ifdef FEATURE_WLAN_BATCH_SCAN
5706 if (fset & WIFI_FEATURE_EXTSCAN) {
5707 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5708 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5709 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5710 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5711 fset |= WIFI_FEATURE_BATCH_SCAN;
5712 }
5713#endif
5714
5715#ifdef FEATURE_WLAN_SCAN_PNO
5716 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5717 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5718 hddLog(LOG1, FL("PNO is supported by firmware"));
5719 fset |= WIFI_FEATURE_PNO;
5720 }
5721#endif
5722
5723 /* STA+STA is supported currently by default */
5724 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5725
5726#ifdef FEATURE_WLAN_TDLS
5727 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5728 sme_IsFeatureSupportedByFW(TDLS)) {
5729 hddLog(LOG1, FL("TDLS is supported by firmware"));
5730 fset |= WIFI_FEATURE_TDLS;
5731 }
5732
5733 /* TDLS_OFFCHANNEL is not supported currently by default */
5734#endif
5735
5736#ifdef WLAN_AP_STA_CONCURRENCY
5737 /* AP+STA concurrency is supported currently by default */
5738 fset |= WIFI_FEATURE_AP_STA;
5739#endif
5740
Mukul Sharma5add0532015-08-17 15:57:47 +05305741#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5742 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5743 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5744#endif
5745
Dasari Srinivas7875a302014-09-26 17:50:57 +05305746 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5747 NLMSG_HDRLEN);
5748
5749 if (!skb) {
5750 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5751 return -EINVAL;
5752 }
5753 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5754
5755 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5756 hddLog(LOGE, FL("nla put fail"));
5757 goto nla_put_failure;
5758 }
5759
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305760 ret = cfg80211_vendor_cmd_reply(skb);
5761 EXIT();
5762 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305763
5764nla_put_failure:
5765 kfree_skb(skb);
5766 return -EINVAL;
5767}
5768
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305769static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305770wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5771 struct wireless_dev *wdev,
5772 const void *data, int data_len)
5773{
5774 int ret = 0;
5775
5776 vos_ssr_protect(__func__);
5777 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5778 vos_ssr_unprotect(__func__);
5779
5780 return ret;
5781}
5782
5783static int
5784__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305785 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305786 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305787{
5788 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5789 uint8_t i, feature_sets, max_feature_sets;
5790 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5791 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305792 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5793 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305794
5795 ENTER();
5796
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305797 ret = wlan_hdd_validate_context(pHddCtx);
5798 if (0 != ret)
5799 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305800 return ret;
5801 }
5802
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305803 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5804 data, data_len, NULL)) {
5805 hddLog(LOGE, FL("Invalid ATTR"));
5806 return -EINVAL;
5807 }
5808
5809 /* Parse and fetch max feature set */
5810 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5811 hddLog(LOGE, FL("Attr max feature set size failed"));
5812 return -EINVAL;
5813 }
5814 max_feature_sets = nla_get_u32(
5815 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5816 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5817
5818 /* Fill feature combination matrix */
5819 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305820 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5821 WIFI_FEATURE_P2P;
5822
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305823 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5824 WIFI_FEATURE_SOFT_AP;
5825
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305826 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5827 WIFI_FEATURE_SOFT_AP;
5828
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305829 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5830 WIFI_FEATURE_SOFT_AP |
5831 WIFI_FEATURE_P2P;
5832
5833 /* Add more feature combinations here */
5834
5835 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5836 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5837 hddLog(LOG1, "Feature set matrix");
5838 for (i = 0; i < feature_sets; i++)
5839 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5840
5841 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5842 sizeof(u32) * feature_sets +
5843 NLMSG_HDRLEN);
5844
5845 if (reply_skb) {
5846 if (nla_put_u32(reply_skb,
5847 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5848 feature_sets) ||
5849 nla_put(reply_skb,
5850 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5851 sizeof(u32) * feature_sets, feature_set_matrix)) {
5852 hddLog(LOGE, FL("nla put fail"));
5853 kfree_skb(reply_skb);
5854 return -EINVAL;
5855 }
5856
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305857 ret = cfg80211_vendor_cmd_reply(reply_skb);
5858 EXIT();
5859 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305860 }
5861 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5862 return -ENOMEM;
5863
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305864}
5865
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305866static int
5867wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5868 struct wireless_dev *wdev,
5869 const void *data, int data_len)
5870{
5871 int ret = 0;
5872
5873 vos_ssr_protect(__func__);
5874 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5875 data_len);
5876 vos_ssr_unprotect(__func__);
5877
5878 return ret;
5879}
5880
Agarwal Ashish738843c2014-09-25 12:27:56 +05305881static const struct nla_policy
5882wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5883 +1] =
5884{
5885 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5886};
5887
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305888static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305889 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305890 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305891 int data_len)
5892{
5893 struct net_device *dev = wdev->netdev;
5894 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5895 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5896 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5897 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5898 eHalStatus status;
5899 u32 dfsFlag = 0;
5900
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305901 ENTER();
5902
Agarwal Ashish738843c2014-09-25 12:27:56 +05305903 status = wlan_hdd_validate_context(pHddCtx);
5904 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305905 return -EINVAL;
5906 }
5907 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5908 data, data_len,
5909 wlan_hdd_set_no_dfs_flag_config_policy)) {
5910 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5911 return -EINVAL;
5912 }
5913
5914 /* Parse and fetch required bandwidth kbps */
5915 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5916 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5917 return -EINVAL;
5918 }
5919
5920 dfsFlag = nla_get_u32(
5921 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5922 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5923 dfsFlag);
5924
5925 pHddCtx->disable_dfs_flag = dfsFlag;
5926
5927 sme_disable_dfs_channel(hHal, dfsFlag);
5928 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305929
5930 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305931 return 0;
5932}
Atul Mittal115287b2014-07-08 13:26:33 +05305933
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305934static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
5935 struct wireless_dev *wdev,
5936 const void *data,
5937 int data_len)
5938{
5939 int ret = 0;
5940
5941 vos_ssr_protect(__func__);
5942 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
5943 vos_ssr_unprotect(__func__);
5944
5945 return ret;
5946
5947}
5948
Mukul Sharma2a271632014-10-13 14:59:01 +05305949const struct
5950nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
5951{
5952 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
5953 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
5954};
5955
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305956static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05305957 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05305958{
5959
5960 u8 bssid[6] = {0};
5961 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5962 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5963 eHalStatus status = eHAL_STATUS_SUCCESS;
5964 v_U32_t isFwrRoamEnabled = FALSE;
5965 int ret;
5966
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305967 ENTER();
5968
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305969 ret = wlan_hdd_validate_context(pHddCtx);
5970 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305971 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05305972 }
5973
5974 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
5975 data, data_len,
5976 qca_wlan_vendor_attr);
5977 if (ret){
5978 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5979 return -EINVAL;
5980 }
5981
5982 /* Parse and fetch Enable flag */
5983 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
5984 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
5985 return -EINVAL;
5986 }
5987
5988 isFwrRoamEnabled = nla_get_u32(
5989 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5990
5991 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5992
5993 /* Parse and fetch bssid */
5994 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5995 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5996 return -EINVAL;
5997 }
5998
5999 memcpy(bssid, nla_data(
6000 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
6001 sizeof(bssid));
6002 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
6003
6004 //Update roaming
6005 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05306006 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05306007 return status;
6008}
6009
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05306010static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
6011 struct wireless_dev *wdev, const void *data, int data_len)
6012{
6013 int ret = 0;
6014
6015 vos_ssr_protect(__func__);
6016 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
6017 vos_ssr_unprotect(__func__);
6018
6019 return ret;
6020}
6021
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306022/**
6023 * __wlan_hdd_cfg80211_setband() - set band
6024 * @wiphy: Pointer to wireless phy
6025 * @wdev: Pointer to wireless device
6026 * @data: Pointer to data
6027 * @data_len: Data length
6028 *
6029 * Return: 0 on success, negative errno on failure
6030 */
6031static int
6032__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6033 struct wireless_dev *wdev,
6034 const void *data,
6035 int data_len)
6036{
6037 struct net_device *dev = wdev->netdev;
6038 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
6039 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
6040 int ret;
6041 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
6042 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
6043
6044 ENTER();
6045
6046 ret = wlan_hdd_validate_context(hdd_ctx);
6047 if (0 != ret) {
6048 hddLog(LOGE, FL("HDD context is not valid"));
6049 return ret;
6050 }
6051
6052 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
6053 policy)) {
6054 hddLog(LOGE, FL("Invalid ATTR"));
6055 return -EINVAL;
6056 }
6057
6058 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
6059 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
6060 return -EINVAL;
6061 }
6062
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306063 hdd_ctx->isSetBandByNL = TRUE;
6064 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306065 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05306066 hdd_ctx->isSetBandByNL = FALSE;
6067
6068 EXIT();
6069 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306070}
6071
6072/**
6073 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
6074 * @wiphy: wiphy structure pointer
6075 * @wdev: Wireless device structure pointer
6076 * @data: Pointer to the data received
6077 * @data_len: Length of @data
6078 *
6079 * Return: 0 on success; errno on failure
6080 */
6081static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
6082 struct wireless_dev *wdev,
6083 const void *data,
6084 int data_len)
6085{
6086 int ret = 0;
6087
6088 vos_ssr_protect(__func__);
6089 ret = __wlan_hdd_cfg80211_setband(wiphy,
6090 wdev, data, data_len);
6091 vos_ssr_unprotect(__func__);
6092
6093 return ret;
6094}
6095
Sunil Duttc69bccb2014-05-26 21:30:20 +05306096const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
6097{
Mukul Sharma2a271632014-10-13 14:59:01 +05306098 {
6099 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6100 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
6101 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6102 WIPHY_VENDOR_CMD_NEED_NETDEV |
6103 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306104 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05306105 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05306106
6107 {
6108 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6109 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
6110 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6111 WIPHY_VENDOR_CMD_NEED_NETDEV |
6112 WIPHY_VENDOR_CMD_NEED_RUNNING,
6113 .doit = wlan_hdd_cfg80211_nan_request
6114 },
6115
Sunil Duttc69bccb2014-05-26 21:30:20 +05306116#ifdef WLAN_FEATURE_LINK_LAYER_STATS
6117 {
6118 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6119 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
6120 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6121 WIPHY_VENDOR_CMD_NEED_NETDEV |
6122 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306123 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05306124 },
6125
6126 {
6127 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6128 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
6129 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6130 WIPHY_VENDOR_CMD_NEED_NETDEV |
6131 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306132 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05306133 },
6134
6135 {
6136 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6137 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
6138 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6139 WIPHY_VENDOR_CMD_NEED_NETDEV |
6140 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306141 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05306142 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05306143#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05306144#ifdef WLAN_FEATURE_EXTSCAN
6145 {
6146 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6147 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
6148 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6149 WIPHY_VENDOR_CMD_NEED_NETDEV |
6150 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306151 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05306152 },
6153 {
6154 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6155 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
6156 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6157 WIPHY_VENDOR_CMD_NEED_NETDEV |
6158 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306159 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05306160 },
6161 {
6162 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6163 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
6164 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6165 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306166 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05306167 },
6168 {
6169 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6170 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
6171 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6172 WIPHY_VENDOR_CMD_NEED_NETDEV |
6173 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306174 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05306175 },
6176 {
6177 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6178 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
6179 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6180 WIPHY_VENDOR_CMD_NEED_NETDEV |
6181 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306182 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05306183 },
6184 {
6185 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6186 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
6187 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6188 WIPHY_VENDOR_CMD_NEED_NETDEV |
6189 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306190 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05306191 },
6192 {
6193 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6194 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
6195 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6196 WIPHY_VENDOR_CMD_NEED_NETDEV |
6197 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306198 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05306199 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05306200 {
6201 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6202 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
6203 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6204 WIPHY_VENDOR_CMD_NEED_NETDEV |
6205 WIPHY_VENDOR_CMD_NEED_RUNNING,
6206 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
6207 },
6208 {
6209 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6210 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
6211 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6212 WIPHY_VENDOR_CMD_NEED_NETDEV |
6213 WIPHY_VENDOR_CMD_NEED_RUNNING,
6214 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
6215 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05306216#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05306217/*EXT TDLS*/
6218 {
6219 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6220 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
6221 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6222 WIPHY_VENDOR_CMD_NEED_NETDEV |
6223 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306224 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05306225 },
6226 {
6227 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6228 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
6229 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6230 WIPHY_VENDOR_CMD_NEED_NETDEV |
6231 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306232 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05306233 },
6234 {
6235 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6236 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
6237 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6238 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306239 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05306240 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05306241 {
6242 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6243 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
6244 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6245 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306246 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05306247 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05306248 {
6249 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6250 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
6251 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6252 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306253 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05306254 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05306255 {
6256 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6257 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
6258 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6259 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306260 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05306261 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306262 {
6263 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6264 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
6265 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6266 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306267 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306268 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306269 {
6270 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6271 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
6272 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6273 WIPHY_VENDOR_CMD_NEED_NETDEV |
6274 WIPHY_VENDOR_CMD_NEED_RUNNING,
6275 .doit = wlan_hdd_cfg80211_setband
6276 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05306277};
6278
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006279/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05306280static const
6281struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006282{
6283#ifdef FEATURE_WLAN_CH_AVOID
6284 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05306285 .vendor_id = QCA_NL80211_VENDOR_ID,
6286 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006287 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05306288#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
6289#ifdef WLAN_FEATURE_LINK_LAYER_STATS
6290 {
6291 /* Index = 1*/
6292 .vendor_id = QCA_NL80211_VENDOR_ID,
6293 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
6294 },
6295 {
6296 /* Index = 2*/
6297 .vendor_id = QCA_NL80211_VENDOR_ID,
6298 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
6299 },
6300 {
6301 /* Index = 3*/
6302 .vendor_id = QCA_NL80211_VENDOR_ID,
6303 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
6304 },
6305 {
6306 /* Index = 4*/
6307 .vendor_id = QCA_NL80211_VENDOR_ID,
6308 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
6309 },
6310 {
6311 /* Index = 5*/
6312 .vendor_id = QCA_NL80211_VENDOR_ID,
6313 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
6314 },
6315 {
6316 /* Index = 6*/
6317 .vendor_id = QCA_NL80211_VENDOR_ID,
6318 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
6319 },
6320#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05306321#ifdef WLAN_FEATURE_EXTSCAN
6322 {
6323 .vendor_id = QCA_NL80211_VENDOR_ID,
6324 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
6325 },
6326 {
6327 .vendor_id = QCA_NL80211_VENDOR_ID,
6328 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
6329 },
6330 {
6331 .vendor_id = QCA_NL80211_VENDOR_ID,
6332 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
6333 },
6334 {
6335 .vendor_id = QCA_NL80211_VENDOR_ID,
6336 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
6337 },
6338 {
6339 .vendor_id = QCA_NL80211_VENDOR_ID,
6340 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
6341 },
6342 {
6343 .vendor_id = QCA_NL80211_VENDOR_ID,
6344 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
6345 },
6346 {
6347 .vendor_id = QCA_NL80211_VENDOR_ID,
6348 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
6349 },
6350 {
6351 .vendor_id = QCA_NL80211_VENDOR_ID,
6352 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
6353 },
6354 {
6355 .vendor_id = QCA_NL80211_VENDOR_ID,
6356 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
6357 },
6358 {
6359 .vendor_id = QCA_NL80211_VENDOR_ID,
6360 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
6361 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05306362 {
6363 .vendor_id = QCA_NL80211_VENDOR_ID,
6364 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
6365 },
6366 {
6367 .vendor_id = QCA_NL80211_VENDOR_ID,
6368 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
6369 },
6370 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
6371 .vendor_id = QCA_NL80211_VENDOR_ID,
6372 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
6373 },
6374 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
6375 .vendor_id = QCA_NL80211_VENDOR_ID,
6376 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
6377 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05306378#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05306379/*EXT TDLS*/
6380 {
6381 .vendor_id = QCA_NL80211_VENDOR_ID,
6382 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
6383 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05306384
6385 {
6386 .vendor_id = QCA_NL80211_VENDOR_ID,
6387 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
6388 },
6389
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006390};
6391
Jeff Johnson295189b2012-06-20 16:38:30 -07006392/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306393 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306394 * This function is called by hdd_wlan_startup()
6395 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306396 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07006397 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306398struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07006399{
6400 struct wiphy *wiphy;
6401 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306402 /*
6403 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07006404 */
6405 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
6406
6407 if (!wiphy)
6408 {
6409 /* Print error and jump into err label and free the memory */
6410 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
6411 return NULL;
6412 }
6413
Sunil Duttc69bccb2014-05-26 21:30:20 +05306414
Jeff Johnson295189b2012-06-20 16:38:30 -07006415 return wiphy;
6416}
6417
6418/*
6419 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306420 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07006421 * private ioctl to change the band value
6422 */
6423int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
6424{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306425 int i, j;
6426 eNVChannelEnabledType channelEnabledState;
6427
Jeff Johnsone7245742012-09-05 17:12:55 -07006428 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306429
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306430 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006431 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306432
6433 if (NULL == wiphy->bands[i])
6434 {
6435 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
6436 __func__, i);
6437 continue;
6438 }
6439
6440 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
6441 {
6442 struct ieee80211_supported_band *band = wiphy->bands[i];
6443
6444 channelEnabledState = vos_nv_getChannelEnabledState(
6445 band->channels[j].hw_value);
6446
6447 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
6448 {
Abhishek Singh678227a2014-11-04 10:52:38 +05306449 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306450 continue;
6451 }
6452 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
6453 {
6454 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6455 continue;
6456 }
6457
6458 if (NV_CHANNEL_DISABLE == channelEnabledState ||
6459 NV_CHANNEL_INVALID == channelEnabledState)
6460 {
6461 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6462 }
6463 else if (NV_CHANNEL_DFS == channelEnabledState)
6464 {
6465 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
6466 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
6467 }
6468 else
6469 {
6470 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
6471 |IEEE80211_CHAN_RADAR);
6472 }
6473 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006474 }
6475 return 0;
6476}
6477/*
6478 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306479 * This function is called by hdd_wlan_startup()
6480 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07006481 * This function is used to initialize and register wiphy structure.
6482 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306483int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07006484 struct wiphy *wiphy,
6485 hdd_config_t *pCfg
6486 )
6487{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306488 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05306489 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6490
Jeff Johnsone7245742012-09-05 17:12:55 -07006491 ENTER();
6492
Jeff Johnson295189b2012-06-20 16:38:30 -07006493 /* Now bind the underlying wlan device with wiphy */
6494 set_wiphy_dev(wiphy, dev);
6495
6496 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07006497
Kiet Lam6c583332013-10-14 05:37:09 +05306498#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07006499 /* the flag for the other case would be initialzed in
6500 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07006501 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05306502#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07006503
Amar Singhalfddc28c2013-09-05 13:03:40 -07006504 /* This will disable updating of NL channels from passive to
6505 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306506#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
6507 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
6508#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07006509 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306510#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07006511
Amar Singhala49cbc52013-10-08 18:37:44 -07006512
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006513#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07006514 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
6515 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
6516 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07006517 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306518#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
6519 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
6520#else
6521 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
6522#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006523#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07006524
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006525#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006526 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08006527#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006528 || pCfg->isFastRoamIniFeatureEnabled
6529#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006530#ifdef FEATURE_WLAN_ESE
6531 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006532#endif
6533 )
6534 {
6535 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
6536 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08006537#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006538#ifdef FEATURE_WLAN_TDLS
6539 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
6540 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
6541#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05306542#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05306543 if (pCfg->configPNOScanSupport)
6544 {
6545 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
6546 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
6547 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
6548 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
6549 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05306550#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006551
Abhishek Singh10d85972015-04-17 10:27:23 +05306552#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6553 wiphy->features |= NL80211_FEATURE_HT_IBSS;
6554#endif
6555
Amar Singhalfddc28c2013-09-05 13:03:40 -07006556#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07006557 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
6558 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07006559 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07006560 driver need to determine what to do with both
6561 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07006562
6563 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07006564#else
6565 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07006566#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006567
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306568 wiphy->max_scan_ssids = MAX_SCAN_SSID;
6569
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05306570 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07006571
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306572 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
6573
Jeff Johnson295189b2012-06-20 16:38:30 -07006574 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05306575 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
6576 | BIT(NL80211_IFTYPE_ADHOC)
6577 | BIT(NL80211_IFTYPE_P2P_CLIENT)
6578 | BIT(NL80211_IFTYPE_P2P_GO)
6579 | BIT(NL80211_IFTYPE_AP);
6580
6581 if (VOS_MONITOR_MODE == hdd_get_conparam())
6582 {
6583 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
6584 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006585
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306586 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006587 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306588#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6589 if( pCfg->enableMCC )
6590 {
6591 /* Currently, supports up to two channels */
6592 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006593
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306594 if( !pCfg->allowMCCGODiffBI )
6595 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006596
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306597 }
6598 wiphy->iface_combinations = &wlan_hdd_iface_combination;
6599 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006600#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306601 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006602
Jeff Johnson295189b2012-06-20 16:38:30 -07006603 /* Before registering we need to update the ht capabilitied based
6604 * on ini values*/
6605 if( !pCfg->ShortGI20MhzEnable )
6606 {
6607 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6608 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6609 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6610 }
6611
6612 if( !pCfg->ShortGI40MhzEnable )
6613 {
6614 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
6615 }
6616
6617 if( !pCfg->nChannelBondingMode5GHz )
6618 {
6619 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6620 }
6621
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306622 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05306623 if (true == hdd_is_5g_supported(pHddCtx))
6624 {
6625 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
6626 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306627
6628 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
6629 {
6630
6631 if (NULL == wiphy->bands[i])
6632 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05306633 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306634 __func__, i);
6635 continue;
6636 }
6637
6638 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
6639 {
6640 struct ieee80211_supported_band *band = wiphy->bands[i];
6641
6642 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
6643 {
6644 // Enable social channels for P2P
6645 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
6646 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
6647 else
6648 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6649 continue;
6650 }
6651 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
6652 {
6653 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6654 continue;
6655 }
6656 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006657 }
6658 /*Initialise the supported cipher suite details*/
6659 wiphy->cipher_suites = hdd_cipher_suites;
6660 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
6661
6662 /*signal strength in mBm (100*dBm) */
6663 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
6664
6665#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05306666 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07006667#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006668
Sunil Duttc69bccb2014-05-26 21:30:20 +05306669 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
6670 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006671 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
6672 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
6673
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306674 EXIT();
6675 return 0;
6676}
6677
6678/* In this function we are registering wiphy. */
6679int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
6680{
6681 ENTER();
6682 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006683 if (0 > wiphy_register(wiphy))
6684 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306685 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07006686 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
6687 return -EIO;
6688 }
6689
6690 EXIT();
6691 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306692}
Jeff Johnson295189b2012-06-20 16:38:30 -07006693
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306694/* In this function we are updating channel list when,
6695 regulatory domain is FCC and country code is US.
6696 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
6697 As per FCC smart phone is not a indoor device.
6698 GO should not opeate on indoor channels */
6699void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
6700{
6701 int j;
6702 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6703 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
6704 //Default counrtycode from NV at the time of wiphy initialization.
6705 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
6706 &defaultCountryCode[0]))
6707 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006708 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306709 }
6710 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
6711 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306712 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
6713 {
6714 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
6715 return;
6716 }
6717 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
6718 {
6719 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
6720 // Mark UNII -1 band channel as passive
6721 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
6722 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
6723 }
6724 }
6725}
6726
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306727/* This function registers for all frame which supplicant is interested in */
6728void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006729{
Jeff Johnson295189b2012-06-20 16:38:30 -07006730 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6731 /* Register for all P2P action, public action etc frames */
6732 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6733
Jeff Johnsone7245742012-09-05 17:12:55 -07006734 ENTER();
6735
Jeff Johnson295189b2012-06-20 16:38:30 -07006736 /* Right now we are registering these frame when driver is getting
6737 initialized. Once we will move to 2.6.37 kernel, in which we have
6738 frame register ops, we will move this code as a part of that */
6739 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306740 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006741 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6742
6743 /* GAS Initial Response */
6744 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6745 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306746
Jeff Johnson295189b2012-06-20 16:38:30 -07006747 /* GAS Comeback Request */
6748 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6749 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6750
6751 /* GAS Comeback Response */
6752 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6753 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6754
6755 /* P2P Public Action */
6756 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306757 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006758 P2P_PUBLIC_ACTION_FRAME_SIZE );
6759
6760 /* P2P Action */
6761 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6762 (v_U8_t*)P2P_ACTION_FRAME,
6763 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07006764
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05306765 /* WNM BSS Transition Request frame */
6766 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6767 (v_U8_t*)WNM_BSS_ACTION_FRAME,
6768 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006769
6770 /* WNM-Notification */
6771 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6772 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6773 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006774}
6775
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306776void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006777{
Jeff Johnson295189b2012-06-20 16:38:30 -07006778 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6779 /* Register for all P2P action, public action etc frames */
6780 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6781
Jeff Johnsone7245742012-09-05 17:12:55 -07006782 ENTER();
6783
Jeff Johnson295189b2012-06-20 16:38:30 -07006784 /* Right now we are registering these frame when driver is getting
6785 initialized. Once we will move to 2.6.37 kernel, in which we have
6786 frame register ops, we will move this code as a part of that */
6787 /* GAS Initial Request */
6788
6789 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6790 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6791
6792 /* GAS Initial Response */
6793 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6794 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306795
Jeff Johnson295189b2012-06-20 16:38:30 -07006796 /* GAS Comeback Request */
6797 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6798 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6799
6800 /* GAS Comeback Response */
6801 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6802 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6803
6804 /* P2P Public Action */
6805 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306806 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006807 P2P_PUBLIC_ACTION_FRAME_SIZE );
6808
6809 /* P2P Action */
6810 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6811 (v_U8_t*)P2P_ACTION_FRAME,
6812 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006813 /* WNM-Notification */
6814 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6815 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6816 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006817}
6818
6819#ifdef FEATURE_WLAN_WAPI
6820void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05306821 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006822{
6823 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6824 tCsrRoamSetKey setKey;
6825 v_BOOL_t isConnected = TRUE;
6826 int status = 0;
6827 v_U32_t roamId= 0xFF;
6828 tANI_U8 *pKeyPtr = NULL;
6829 int n = 0;
6830
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306831 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
6832 __func__, hdd_device_modetoString(pAdapter->device_mode),
6833 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006834
Gopichand Nakkalae7480202013-02-11 15:24:22 +05306835 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006836 setKey.keyId = key_index; // Store Key ID
6837 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
6838 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
6839 setKey.paeRole = 0 ; // the PAE role
6840 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
6841 {
6842 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
6843 }
6844 else
6845 {
6846 isConnected = hdd_connIsConnected(pHddStaCtx);
6847 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
6848 }
6849 setKey.keyLength = key_Len;
6850 pKeyPtr = setKey.Key;
6851 memcpy( pKeyPtr, key, key_Len);
6852
Arif Hussain6d2a3322013-11-17 19:50:10 -08006853 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07006854 __func__, key_Len);
6855 for (n = 0 ; n < key_Len; n++)
6856 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
6857 __func__,n,setKey.Key[n]);
6858
6859 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
6860 if ( isConnected )
6861 {
6862 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
6863 pAdapter->sessionId, &setKey, &roamId );
6864 }
6865 if ( status != 0 )
6866 {
6867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6868 "[%4d] sme_RoamSetKey returned ERROR status= %d",
6869 __LINE__, status );
6870 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
6871 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05306872 /* Need to clear any trace of key value in the memory.
6873 * Thus zero out the memory even though it is local
6874 * variable.
6875 */
6876 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006877}
6878#endif /* FEATURE_WLAN_WAPI*/
6879
6880#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306881int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006882 beacon_data_t **ppBeacon,
6883 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006884#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306885int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006886 beacon_data_t **ppBeacon,
6887 struct cfg80211_beacon_data *params,
6888 int dtim_period)
6889#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306890{
Jeff Johnson295189b2012-06-20 16:38:30 -07006891 int size;
6892 beacon_data_t *beacon = NULL;
6893 beacon_data_t *old = NULL;
6894 int head_len,tail_len;
6895
Jeff Johnsone7245742012-09-05 17:12:55 -07006896 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006897 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306898 {
6899 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6900 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006901 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306902 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006903
6904 old = pAdapter->sessionCtx.ap.beacon;
6905
6906 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306907 {
6908 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6909 FL("session(%d) old and new heads points to NULL"),
6910 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006911 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306912 }
6913
6914 if (params->tail && !params->tail_len)
6915 {
6916 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6917 FL("tail_len is zero but tail is not NULL"));
6918 return -EINVAL;
6919 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006920
Jeff Johnson295189b2012-06-20 16:38:30 -07006921#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
6922 /* Kernel 3.0 is not updating dtim_period for set beacon */
6923 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306924 {
6925 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6926 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006927 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306928 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006929#endif
6930
6931 if(params->head)
6932 head_len = params->head_len;
6933 else
6934 head_len = old->head_len;
6935
6936 if(params->tail || !old)
6937 tail_len = params->tail_len;
6938 else
6939 tail_len = old->tail_len;
6940
6941 size = sizeof(beacon_data_t) + head_len + tail_len;
6942
6943 beacon = kzalloc(size, GFP_KERNEL);
6944
6945 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306946 {
6947 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6948 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006949 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306950 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006951
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006952#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006953 if(params->dtim_period || !old )
6954 beacon->dtim_period = params->dtim_period;
6955 else
6956 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006957#else
6958 if(dtim_period || !old )
6959 beacon->dtim_period = dtim_period;
6960 else
6961 beacon->dtim_period = old->dtim_period;
6962#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306963
Jeff Johnson295189b2012-06-20 16:38:30 -07006964 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6965 beacon->tail = beacon->head + head_len;
6966 beacon->head_len = head_len;
6967 beacon->tail_len = tail_len;
6968
6969 if(params->head) {
6970 memcpy (beacon->head,params->head,beacon->head_len);
6971 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306972 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07006973 if(old)
6974 memcpy (beacon->head,old->head,beacon->head_len);
6975 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306976
Jeff Johnson295189b2012-06-20 16:38:30 -07006977 if(params->tail) {
6978 memcpy (beacon->tail,params->tail,beacon->tail_len);
6979 }
6980 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306981 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07006982 memcpy (beacon->tail,old->tail,beacon->tail_len);
6983 }
6984
6985 *ppBeacon = beacon;
6986
6987 kfree(old);
6988
6989 return 0;
6990
6991}
Jeff Johnson295189b2012-06-20 16:38:30 -07006992
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05306993v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
6994#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6995 const v_U8_t *pIes,
6996#else
6997 v_U8_t *pIes,
6998#endif
6999 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007000{
7001 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05307002 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07007003 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307004
Jeff Johnson295189b2012-06-20 16:38:30 -07007005 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307006 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007007 elem_id = ptr[0];
7008 elem_len = ptr[1];
7009 left -= 2;
7010 if(elem_len > left)
7011 {
7012 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007013 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007014 eid,elem_len,left);
7015 return NULL;
7016 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307017 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07007018 {
7019 return ptr;
7020 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307021
Jeff Johnson295189b2012-06-20 16:38:30 -07007022 left -= elem_len;
7023 ptr += (elem_len + 2);
7024 }
7025 return NULL;
7026}
7027
Jeff Johnson295189b2012-06-20 16:38:30 -07007028/* Check if rate is 11g rate or not */
7029static int wlan_hdd_rate_is_11g(u8 rate)
7030{
Sanjay Devnani28322e22013-06-21 16:13:40 -07007031 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07007032 u8 i;
7033 for (i = 0; i < 8; i++)
7034 {
7035 if(rate == gRateArray[i])
7036 return TRUE;
7037 }
7038 return FALSE;
7039}
7040
7041/* Check for 11g rate and set proper 11g only mode */
7042static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
7043 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
7044{
7045 u8 i, num_rates = pIe[0];
7046
7047 pIe += 1;
7048 for ( i = 0; i < num_rates; i++)
7049 {
7050 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
7051 {
7052 /* If rate set have 11g rate than change the mode to 11G */
7053 *pSapHw_mode = eSAP_DOT11_MODE_11g;
7054 if (pIe[i] & BASIC_RATE_MASK)
7055 {
7056 /* If we have 11g rate as basic rate, it means mode
7057 is 11g only mode.
7058 */
7059 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
7060 *pCheckRatesfor11g = FALSE;
7061 }
7062 }
7063 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
7064 {
7065 *require_ht = TRUE;
7066 }
7067 }
7068 return;
7069}
7070
7071static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
7072{
7073 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7074 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7075 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
7076 u8 checkRatesfor11g = TRUE;
7077 u8 require_ht = FALSE;
7078 u8 *pIe=NULL;
7079
7080 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
7081
7082 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
7083 pBeacon->head_len, WLAN_EID_SUPP_RATES);
7084 if (pIe != NULL)
7085 {
7086 pIe += 1;
7087 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
7088 &pConfig->SapHw_mode);
7089 }
7090
7091 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7092 WLAN_EID_EXT_SUPP_RATES);
7093 if (pIe != NULL)
7094 {
7095
7096 pIe += 1;
7097 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
7098 &pConfig->SapHw_mode);
7099 }
7100
7101 if( pConfig->channel > 14 )
7102 {
7103 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
7104 }
7105
7106 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
7107 WLAN_EID_HT_CAPABILITY);
7108
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307109 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07007110 {
7111 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
7112 if(require_ht)
7113 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
7114 }
7115}
7116
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307117static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
7118 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
7119{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07007120 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307121 v_U8_t *pIe = NULL;
7122 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7123
7124 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
7125 pBeacon->tail, pBeacon->tail_len);
7126
7127 if (pIe)
7128 {
7129 ielen = pIe[1] + 2;
7130 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
7131 {
7132 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
7133 }
7134 else
7135 {
7136 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
7137 return -EINVAL;
7138 }
7139 *total_ielen += ielen;
7140 }
7141 return 0;
7142}
7143
Arif Hussaine7f3ea52013-09-12 21:56:36 -07007144static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
7145 v_U8_t *genie, v_U8_t *total_ielen)
7146{
7147 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7148 int left = pBeacon->tail_len;
7149 v_U8_t *ptr = pBeacon->tail;
7150 v_U8_t elem_id, elem_len;
7151 v_U16_t ielen = 0;
7152
7153 if ( NULL == ptr || 0 == left )
7154 return;
7155
7156 while (left >= 2)
7157 {
7158 elem_id = ptr[0];
7159 elem_len = ptr[1];
7160 left -= 2;
7161 if (elem_len > left)
7162 {
7163 hddLog( VOS_TRACE_LEVEL_ERROR,
7164 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
7165 elem_id, elem_len, left);
7166 return;
7167 }
7168 if (IE_EID_VENDOR == elem_id)
7169 {
7170 /* skipping the VSIE's which we don't want to include or
7171 * it will be included by existing code
7172 */
7173 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
7174#ifdef WLAN_FEATURE_WFD
7175 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
7176#endif
7177 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
7178 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
7179 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
7180 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
7181 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
7182 {
7183 ielen = ptr[1] + 2;
7184 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
7185 {
7186 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
7187 *total_ielen += ielen;
7188 }
7189 else
7190 {
7191 hddLog( VOS_TRACE_LEVEL_ERROR,
7192 "IE Length is too big "
7193 "IEs eid=%d elem_len=%d total_ie_lent=%d",
7194 elem_id, elem_len, *total_ielen);
7195 }
7196 }
7197 }
7198
7199 left -= elem_len;
7200 ptr += (elem_len + 2);
7201 }
7202 return;
7203}
7204
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007205#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007206static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
7207 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007208#else
7209static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
7210 struct cfg80211_beacon_data *params)
7211#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007212{
7213 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307214 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007215 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07007216 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007217
7218 genie = vos_mem_malloc(MAX_GENIE_LEN);
7219
7220 if(genie == NULL) {
7221
7222 return -ENOMEM;
7223 }
7224
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307225 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7226 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007227 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307228 hddLog(LOGE,
7229 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307230 ret = -EINVAL;
7231 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007232 }
7233
7234#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307235 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7236 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
7237 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307238 hddLog(LOGE,
7239 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307240 ret = -EINVAL;
7241 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007242 }
7243#endif
7244
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307245 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7246 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007247 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307248 hddLog(LOGE,
7249 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307250 ret = -EINVAL;
7251 goto done;
7252 }
7253
7254 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
7255 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07007256 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07007257 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007258
7259 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7260 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
7261 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
7262 {
7263 hddLog(LOGE,
7264 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007265 ret = -EINVAL;
7266 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007267 }
7268
7269 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7270 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
7271 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7272 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7273 ==eHAL_STATUS_FAILURE)
7274 {
7275 hddLog(LOGE,
7276 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007277 ret = -EINVAL;
7278 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007279 }
7280
7281 // Added for ProResp IE
7282 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
7283 {
7284 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
7285 u8 probe_rsp_ie_len[3] = {0};
7286 u8 counter = 0;
7287 /* Check Probe Resp Length if it is greater then 255 then Store
7288 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
7289 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
7290 Store More then 255 bytes into One Variable.
7291 */
7292 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
7293 {
7294 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
7295 {
7296 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
7297 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
7298 }
7299 else
7300 {
7301 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
7302 rem_probe_resp_ie_len = 0;
7303 }
7304 }
7305
7306 rem_probe_resp_ie_len = 0;
7307
7308 if (probe_rsp_ie_len[0] > 0)
7309 {
7310 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7311 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
7312 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7313 probe_rsp_ie_len[0], NULL,
7314 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7315 {
7316 hddLog(LOGE,
7317 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007318 ret = -EINVAL;
7319 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007320 }
7321 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
7322 }
7323
7324 if (probe_rsp_ie_len[1] > 0)
7325 {
7326 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7327 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
7328 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7329 probe_rsp_ie_len[1], NULL,
7330 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7331 {
7332 hddLog(LOGE,
7333 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007334 ret = -EINVAL;
7335 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007336 }
7337 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
7338 }
7339
7340 if (probe_rsp_ie_len[2] > 0)
7341 {
7342 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7343 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
7344 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7345 probe_rsp_ie_len[2], NULL,
7346 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7347 {
7348 hddLog(LOGE,
7349 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007350 ret = -EINVAL;
7351 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007352 }
7353 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
7354 }
7355
7356 if (probe_rsp_ie_len[1] == 0 )
7357 {
7358 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7359 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7360 eANI_BOOLEAN_FALSE) )
7361 {
7362 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007363 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007364 }
7365 }
7366
7367 if (probe_rsp_ie_len[2] == 0 )
7368 {
7369 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7370 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7371 eANI_BOOLEAN_FALSE) )
7372 {
7373 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007374 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007375 }
7376 }
7377
7378 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7379 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
7380 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7381 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7382 == eHAL_STATUS_FAILURE)
7383 {
7384 hddLog(LOGE,
7385 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007386 ret = -EINVAL;
7387 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007388 }
7389 }
7390 else
7391 {
7392 // Reset WNI_CFG_PROBE_RSP Flags
7393 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
7394
7395 hddLog(VOS_TRACE_LEVEL_INFO,
7396 "%s: No Probe Response IE received in set beacon",
7397 __func__);
7398 }
7399
7400 // Added for AssocResp IE
7401 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
7402 {
7403 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7404 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
7405 params->assocresp_ies_len, NULL,
7406 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7407 {
7408 hddLog(LOGE,
7409 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007410 ret = -EINVAL;
7411 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007412 }
7413
7414 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7415 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
7416 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7417 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7418 == eHAL_STATUS_FAILURE)
7419 {
7420 hddLog(LOGE,
7421 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007422 ret = -EINVAL;
7423 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007424 }
7425 }
7426 else
7427 {
7428 hddLog(VOS_TRACE_LEVEL_INFO,
7429 "%s: No Assoc Response IE received in set beacon",
7430 __func__);
7431
7432 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7433 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7434 eANI_BOOLEAN_FALSE) )
7435 {
7436 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007437 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007438 }
7439 }
7440
Jeff Johnsone7245742012-09-05 17:12:55 -07007441done:
Jeff Johnson295189b2012-06-20 16:38:30 -07007442 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307443 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007444}
Jeff Johnson295189b2012-06-20 16:38:30 -07007445
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307446/*
Jeff Johnson295189b2012-06-20 16:38:30 -07007447 * FUNCTION: wlan_hdd_validate_operation_channel
7448 * called by wlan_hdd_cfg80211_start_bss() and
7449 * wlan_hdd_cfg80211_set_channel()
7450 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307451 * channel list.
7452 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007453VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07007454{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307455
Jeff Johnson295189b2012-06-20 16:38:30 -07007456 v_U32_t num_ch = 0;
7457 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7458 u32 indx = 0;
7459 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307460 v_U8_t fValidChannel = FALSE, count = 0;
7461 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307462
Jeff Johnson295189b2012-06-20 16:38:30 -07007463 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7464
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307465 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07007466 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307467 /* Validate the channel */
7468 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007469 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307470 if ( channel == rfChannels[count].channelNum )
7471 {
7472 fValidChannel = TRUE;
7473 break;
7474 }
7475 }
7476 if (fValidChannel != TRUE)
7477 {
7478 hddLog(VOS_TRACE_LEVEL_ERROR,
7479 "%s: Invalid Channel [%d]", __func__, channel);
7480 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007481 }
7482 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307483 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007484 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307485 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7486 valid_ch, &num_ch))
7487 {
7488 hddLog(VOS_TRACE_LEVEL_ERROR,
7489 "%s: failed to get valid channel list", __func__);
7490 return VOS_STATUS_E_FAILURE;
7491 }
7492 for (indx = 0; indx < num_ch; indx++)
7493 {
7494 if (channel == valid_ch[indx])
7495 {
7496 break;
7497 }
7498 }
7499
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05307500 if (indx >= num_ch)
7501 {
7502 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
7503 {
7504 eCsrBand band;
7505 unsigned int freq;
7506
7507 sme_GetFreqBand(hHal, &band);
7508
7509 if (eCSR_BAND_5G == band)
7510 {
7511#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
7512 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
7513 {
7514 freq = ieee80211_channel_to_frequency(channel,
7515 IEEE80211_BAND_2GHZ);
7516 }
7517 else
7518 {
7519 freq = ieee80211_channel_to_frequency(channel,
7520 IEEE80211_BAND_5GHZ);
7521 }
7522#else
7523 freq = ieee80211_channel_to_frequency(channel);
7524#endif
7525 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
7526 return VOS_STATUS_SUCCESS;
7527 }
7528 }
7529
7530 hddLog(VOS_TRACE_LEVEL_ERROR,
7531 "%s: Invalid Channel [%d]", __func__, channel);
7532 return VOS_STATUS_E_FAILURE;
7533 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007534 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05307535
Jeff Johnson295189b2012-06-20 16:38:30 -07007536 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307537
Jeff Johnson295189b2012-06-20 16:38:30 -07007538}
7539
Viral Modi3a32cc52013-02-08 11:14:52 -08007540/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307541 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08007542 * This function is used to set the channel number
7543 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307544static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08007545 struct ieee80211_channel *chan,
7546 enum nl80211_channel_type channel_type
7547 )
7548{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307549 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08007550 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07007551 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08007552 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307553 hdd_context_t *pHddCtx;
7554 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007555
7556 ENTER();
7557
7558 if( NULL == dev )
7559 {
7560 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007561 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08007562 return -ENODEV;
7563 }
7564 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307565
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307566 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7567 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
7568 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08007569 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307570 "%s: device_mode = %s (%d) freq = %d", __func__,
7571 hdd_device_modetoString(pAdapter->device_mode),
7572 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307573
7574 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7575 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307576 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08007577 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307578 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007579 }
7580
7581 /*
7582 * Do freq to chan conversion
7583 * TODO: for 11a
7584 */
7585
7586 channel = ieee80211_frequency_to_channel(freq);
7587
7588 /* Check freq range */
7589 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
7590 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
7591 {
7592 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007593 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08007594 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
7595 WNI_CFG_CURRENT_CHANNEL_STAMAX);
7596 return -EINVAL;
7597 }
7598
7599 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7600
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05307601 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
7602 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08007603 {
7604 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
7605 {
7606 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007607 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08007608 return -EINVAL;
7609 }
7610 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7611 "%s: set channel to [%d] for device mode =%d",
7612 __func__, channel,pAdapter->device_mode);
7613 }
7614 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08007615 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08007616 )
7617 {
7618 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7619 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
7620 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7621
7622 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
7623 {
7624 /* Link is up then return cant set channel*/
7625 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007626 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08007627 return -EINVAL;
7628 }
7629
7630 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
7631 pHddStaCtx->conn_info.operationChannel = channel;
7632 pRoamProfile->ChannelInfo.ChannelList =
7633 &pHddStaCtx->conn_info.operationChannel;
7634 }
7635 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08007636 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08007637 )
7638 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307639 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
7640 {
7641 if(VOS_STATUS_SUCCESS !=
7642 wlan_hdd_validate_operation_channel(pAdapter,channel))
7643 {
7644 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007645 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307646 return -EINVAL;
7647 }
7648 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7649 }
7650 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08007651 {
7652 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
7653
7654 /* If auto channel selection is configured as enable/ 1 then ignore
7655 channel set by supplicant
7656 */
7657 if ( cfg_param->apAutoChannelSelection )
7658 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307659 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
7660 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08007661 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307662 "%s: set channel to auto channel (0) for device mode =%s (%d)",
7663 __func__, hdd_device_modetoString(pAdapter->device_mode),
7664 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08007665 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307666 else
7667 {
7668 if(VOS_STATUS_SUCCESS !=
7669 wlan_hdd_validate_operation_channel(pAdapter,channel))
7670 {
7671 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007672 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307673 return -EINVAL;
7674 }
7675 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7676 }
Viral Modi3a32cc52013-02-08 11:14:52 -08007677 }
7678 }
7679 else
7680 {
7681 hddLog(VOS_TRACE_LEVEL_FATAL,
7682 "%s: Invalid device mode failed to set valid channel", __func__);
7683 return -EINVAL;
7684 }
7685 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307686 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007687}
7688
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307689static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
7690 struct net_device *dev,
7691 struct ieee80211_channel *chan,
7692 enum nl80211_channel_type channel_type
7693 )
7694{
7695 int ret;
7696
7697 vos_ssr_protect(__func__);
7698 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
7699 vos_ssr_unprotect(__func__);
7700
7701 return ret;
7702}
7703
Jeff Johnson295189b2012-06-20 16:38:30 -07007704#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7705static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7706 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007707#else
7708static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7709 struct cfg80211_beacon_data *params,
7710 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307711 enum nl80211_hidden_ssid hidden_ssid,
7712 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007713#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007714{
7715 tsap_Config_t *pConfig;
7716 beacon_data_t *pBeacon = NULL;
7717 struct ieee80211_mgmt *pMgmt_frame;
7718 v_U8_t *pIe=NULL;
7719 v_U16_t capab_info;
7720 eCsrAuthType RSNAuthType;
7721 eCsrEncryptionType RSNEncryptType;
7722 eCsrEncryptionType mcRSNEncryptType;
7723 int status = VOS_STATUS_SUCCESS;
7724 tpWLAN_SAPEventCB pSapEventCallback;
7725 hdd_hostapd_state_t *pHostapdState;
7726 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
7727 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307728 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007729 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307730 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07007731 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08007732 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05307733 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07007734 v_BOOL_t MFPCapable = VOS_FALSE;
7735 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307736 v_BOOL_t sapEnable11AC =
7737 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07007738 ENTER();
7739
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307740 iniConfig = pHddCtx->cfg_ini;
7741
Jeff Johnson295189b2012-06-20 16:38:30 -07007742 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
7743
7744 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7745
7746 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7747
7748 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
7749
7750 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
7751
7752 //channel is already set in the set_channel Call back
7753 //pConfig->channel = pCommitConfig->channel;
7754
7755 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307756 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07007757 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
7758
7759 pConfig->dtim_period = pBeacon->dtim_period;
7760
Arif Hussain6d2a3322013-11-17 19:50:10 -08007761 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07007762 pConfig->dtim_period);
7763
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08007764 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07007765 {
7766 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007767 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05307768 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
7769 {
7770 tANI_BOOLEAN restartNeeded;
7771 pConfig->ieee80211d = 1;
7772 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
7773 sme_setRegInfo(hHal, pConfig->countryCode);
7774 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
7775 }
7776 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07007777 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07007778 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07007779 pConfig->ieee80211d = 1;
7780 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
7781 sme_setRegInfo(hHal, pConfig->countryCode);
7782 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07007783 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007784 else
7785 {
7786 pConfig->ieee80211d = 0;
7787 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307788 /*
7789 * If auto channel is configured i.e. channel is 0,
7790 * so skip channel validation.
7791 */
7792 if( AUTO_CHANNEL_SELECT != pConfig->channel )
7793 {
7794 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
7795 {
7796 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007797 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307798 return -EINVAL;
7799 }
7800 }
7801 else
7802 {
7803 if(1 != pHddCtx->is_dynamic_channel_range_set)
7804 {
7805 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
7806 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
7807 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
7808 }
7809 pHddCtx->is_dynamic_channel_range_set = 0;
7810 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007811 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007812 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007813 {
7814 pConfig->ieee80211d = 0;
7815 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307816
7817#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7818 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7819 pConfig->authType = eSAP_OPEN_SYSTEM;
7820 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7821 pConfig->authType = eSAP_SHARED_KEY;
7822 else
7823 pConfig->authType = eSAP_AUTO_SWITCH;
7824#else
7825 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7826 pConfig->authType = eSAP_OPEN_SYSTEM;
7827 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7828 pConfig->authType = eSAP_SHARED_KEY;
7829 else
7830 pConfig->authType = eSAP_AUTO_SWITCH;
7831#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007832
7833 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307834
7835 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07007836 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
7837
7838 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
7839
7840 /*Set wps station to configured*/
7841 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
7842
7843 if(pIe)
7844 {
7845 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
7846 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007847 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07007848 return -EINVAL;
7849 }
7850 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
7851 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007852 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07007853 /* Check 15 bit of WPS IE as it contain information for wps state
7854 * WPS state
7855 */
7856 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
7857 {
7858 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
7859 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
7860 {
7861 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
7862 }
7863 }
7864 }
7865 else
7866 {
7867 pConfig->wps_state = SAP_WPS_DISABLED;
7868 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307869 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07007870
c_hpothufe599e92014-06-16 11:38:55 +05307871 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7872 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7873 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
7874 eCSR_ENCRYPT_TYPE_NONE;
7875
Jeff Johnson295189b2012-06-20 16:38:30 -07007876 pConfig->RSNWPAReqIELength = 0;
7877 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307878 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007879 WLAN_EID_RSN);
7880 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307881 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007882 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7883 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7884 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307885 /* The actual processing may eventually be more extensive than
7886 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07007887 * by the app.
7888 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307889 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007890 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7891 &RSNEncryptType,
7892 &mcRSNEncryptType,
7893 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007894 &MFPCapable,
7895 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007896 pConfig->pRSNWPAReqIE[1]+2,
7897 pConfig->pRSNWPAReqIE );
7898
7899 if( VOS_STATUS_SUCCESS == status )
7900 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307901 /* Now copy over all the security attributes you have
7902 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007903 * */
7904 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7905 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7906 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7907 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307908 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007909 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007910 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7911 }
7912 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307913
Jeff Johnson295189b2012-06-20 16:38:30 -07007914 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7915 pBeacon->tail, pBeacon->tail_len);
7916
7917 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
7918 {
7919 if (pConfig->pRSNWPAReqIE)
7920 {
7921 /*Mixed mode WPA/WPA2*/
7922 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
7923 pConfig->RSNWPAReqIELength += pIe[1] + 2;
7924 }
7925 else
7926 {
7927 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7928 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7929 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307930 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007931 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7932 &RSNEncryptType,
7933 &mcRSNEncryptType,
7934 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007935 &MFPCapable,
7936 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007937 pConfig->pRSNWPAReqIE[1]+2,
7938 pConfig->pRSNWPAReqIE );
7939
7940 if( VOS_STATUS_SUCCESS == status )
7941 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307942 /* Now copy over all the security attributes you have
7943 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007944 * */
7945 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7946 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7947 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7948 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307949 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007950 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007951 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7952 }
7953 }
7954 }
7955
Jeff Johnson4416a782013-03-25 14:17:50 -07007956 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
7957 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
7958 return -EINVAL;
7959 }
7960
Jeff Johnson295189b2012-06-20 16:38:30 -07007961 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
7962
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007963#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007964 if (params->ssid != NULL)
7965 {
7966 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
7967 pConfig->SSIDinfo.ssid.length = params->ssid_len;
7968 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7969 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7970 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007971#else
7972 if (ssid != NULL)
7973 {
7974 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
7975 pConfig->SSIDinfo.ssid.length = ssid_len;
7976 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7977 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7978 }
7979#endif
7980
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307981 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07007982 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307983
Jeff Johnson295189b2012-06-20 16:38:30 -07007984 /* default value */
7985 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7986 pConfig->num_accept_mac = 0;
7987 pConfig->num_deny_mac = 0;
7988
7989 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7990 pBeacon->tail, pBeacon->tail_len);
7991
7992 /* pIe for black list is following form:
7993 type : 1 byte
7994 length : 1 byte
7995 OUI : 4 bytes
7996 acl type : 1 byte
7997 no of mac addr in black list: 1 byte
7998 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307999 */
8000 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008001 {
8002 pConfig->SapMacaddr_acl = pIe[6];
8003 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08008004 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008005 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308006 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
8007 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008008 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
8009 for (i = 0; i < pConfig->num_deny_mac; i++)
8010 {
8011 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
8012 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308013 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008014 }
8015 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
8016 pBeacon->tail, pBeacon->tail_len);
8017
8018 /* pIe for white list is following form:
8019 type : 1 byte
8020 length : 1 byte
8021 OUI : 4 bytes
8022 acl type : 1 byte
8023 no of mac addr in white list: 1 byte
8024 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308025 */
8026 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008027 {
8028 pConfig->SapMacaddr_acl = pIe[6];
8029 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08008030 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07008031 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308032 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
8033 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008034 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
8035 for (i = 0; i < pConfig->num_accept_mac; i++)
8036 {
8037 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
8038 acl_entry++;
8039 }
8040 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05308041
Jeff Johnson295189b2012-06-20 16:38:30 -07008042 wlan_hdd_set_sapHwmode(pHostapdAdapter);
8043
Jeff Johnsone7245742012-09-05 17:12:55 -07008044#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08008045 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05308046 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
8047 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05308048 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
8049 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08008050 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
8051 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05308052 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
8053 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07008054 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05308055 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07008056 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05308057 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07008058
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05308059 /* If ACS disable and selected channel <= 14
8060 * OR
8061 * ACS enabled and ACS operating band is choosen as 2.4
8062 * AND
8063 * VHT in 2.4G Disabled
8064 * THEN
8065 * Fallback to 11N mode
8066 */
8067 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
8068 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05308069 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05308070 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07008071 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05308072 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
8073 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07008074 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
8075 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008076 }
8077#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308078
Jeff Johnson295189b2012-06-20 16:38:30 -07008079 // ht_capab is not what the name conveys,this is used for protection bitmap
8080 pConfig->ht_capab =
8081 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
8082
8083 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
8084 {
8085 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
8086 return -EINVAL;
8087 }
8088
8089 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308090 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07008091 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
8092 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308093 pConfig->obssProtEnabled =
8094 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07008095
Chet Lanctot8cecea22014-02-11 19:09:36 -08008096#ifdef WLAN_FEATURE_11W
8097 pConfig->mfpCapable = MFPCapable;
8098 pConfig->mfpRequired = MFPRequired;
8099 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
8100 pConfig->mfpCapable, pConfig->mfpRequired);
8101#endif
8102
Arif Hussain6d2a3322013-11-17 19:50:10 -08008103 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07008104 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08008105 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
8106 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
8107 (int)pConfig->channel);
8108 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
8109 pConfig->SapHw_mode, pConfig->privacy,
8110 pConfig->authType);
8111 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
8112 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
8113 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
8114 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07008115
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308116 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07008117 {
8118 //Bss already started. just return.
8119 //TODO Probably it should update some beacon params.
8120 hddLog( LOGE, "Bss Already started...Ignore the request");
8121 EXIT();
8122 return 0;
8123 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308124
Agarwal Ashish51325b52014-06-16 16:50:49 +05308125 if (vos_max_concurrent_connections_reached()) {
8126 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8127 return -EINVAL;
8128 }
8129
Jeff Johnson295189b2012-06-20 16:38:30 -07008130 pConfig->persona = pHostapdAdapter->device_mode;
8131
Peng Xu2446a892014-09-05 17:21:18 +05308132 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
8133 if ( NULL != psmeConfig)
8134 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05308135 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05308136 sme_GetConfigParam(hHal, psmeConfig);
8137 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05308138#ifdef WLAN_FEATURE_AP_HT40_24G
8139 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
8140 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
8141 && pHddCtx->cfg_ini->apHT40_24GEnabled)
8142 {
8143 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
8144 sme_UpdateConfig (hHal, psmeConfig);
8145 }
8146#endif
Peng Xu2446a892014-09-05 17:21:18 +05308147 vos_mem_free(psmeConfig);
8148 }
Peng Xuafc34e32014-09-25 13:23:55 +05308149 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05308150
Jeff Johnson295189b2012-06-20 16:38:30 -07008151 pSapEventCallback = hdd_hostapd_SAPEventCB;
8152 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
8153 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
8154 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08008155 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008156 return -EINVAL;
8157 }
8158
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308159 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07008160 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
8161
8162 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308163
Jeff Johnson295189b2012-06-20 16:38:30 -07008164 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308165 {
8166 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008167 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07008168 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07008169 VOS_ASSERT(0);
8170 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308171
Jeff Johnson295189b2012-06-20 16:38:30 -07008172 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05308173 /* Initialize WMM configuation */
8174 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05308175 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008176
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008177#ifdef WLAN_FEATURE_P2P_DEBUG
8178 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
8179 {
8180 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
8181 {
8182 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
8183 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08008184 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008185 }
8186 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
8187 {
8188 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
8189 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08008190 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008191 }
8192 }
8193#endif
8194
Jeff Johnson295189b2012-06-20 16:38:30 -07008195 pHostapdState->bCommit = TRUE;
8196 EXIT();
8197
8198 return 0;
8199}
8200
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008201#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308202static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308203 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008204 struct beacon_parameters *params)
8205{
8206 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308207 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308208 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008209
8210 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308211
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308212 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8213 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
8214 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308215 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
8216 hdd_device_modetoString(pAdapter->device_mode),
8217 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008218
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308219 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8220 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308221 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008222 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308223 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008224 }
8225
Agarwal Ashish51325b52014-06-16 16:50:49 +05308226 if (vos_max_concurrent_connections_reached()) {
8227 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8228 return -EINVAL;
8229 }
8230
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308231 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008232 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008233 )
8234 {
8235 beacon_data_t *old,*new;
8236
8237 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308238
Jeff Johnson295189b2012-06-20 16:38:30 -07008239 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308240 {
8241 hddLog(VOS_TRACE_LEVEL_WARN,
8242 FL("already beacon info added to session(%d)"),
8243 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008244 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308245 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008246
8247 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
8248
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308249 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07008250 {
8251 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008252 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008253 return -EINVAL;
8254 }
8255
8256 pAdapter->sessionCtx.ap.beacon = new;
8257
8258 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
8259 }
8260
8261 EXIT();
8262 return status;
8263}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308264
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308265static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
8266 struct net_device *dev,
8267 struct beacon_parameters *params)
8268{
8269 int ret;
8270
8271 vos_ssr_protect(__func__);
8272 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
8273 vos_ssr_unprotect(__func__);
8274
8275 return ret;
8276}
8277
8278static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008279 struct net_device *dev,
8280 struct beacon_parameters *params)
8281{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308282 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308283 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8284 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308285 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008286
8287 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308288
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308289 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8290 TRACE_CODE_HDD_CFG80211_SET_BEACON,
8291 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
8292 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8293 __func__, hdd_device_modetoString(pAdapter->device_mode),
8294 pAdapter->device_mode);
8295
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308296 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8297 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308298 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008299 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308300 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008301 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308302
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308303 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008304 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308305 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008306 {
8307 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308308
Jeff Johnson295189b2012-06-20 16:38:30 -07008309 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308310
Jeff Johnson295189b2012-06-20 16:38:30 -07008311 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308312 {
8313 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8314 FL("session(%d) old and new heads points to NULL"),
8315 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008316 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308317 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008318
8319 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
8320
8321 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308322 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008323 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008324 return -EINVAL;
8325 }
8326
8327 pAdapter->sessionCtx.ap.beacon = new;
8328
8329 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
8330 }
8331
8332 EXIT();
8333 return status;
8334}
8335
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308336static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
8337 struct net_device *dev,
8338 struct beacon_parameters *params)
8339{
8340 int ret;
8341
8342 vos_ssr_protect(__func__);
8343 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
8344 vos_ssr_unprotect(__func__);
8345
8346 return ret;
8347}
8348
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008349#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8350
8351#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308352static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008353 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008354#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308355static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008356 struct net_device *dev)
8357#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008358{
8359 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07008360 hdd_context_t *pHddCtx = NULL;
8361 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308362 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308363 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008364
8365 ENTER();
8366
8367 if (NULL == pAdapter)
8368 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308369 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008370 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008371 return -ENODEV;
8372 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008373
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308374 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8375 TRACE_CODE_HDD_CFG80211_STOP_AP,
8376 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308377 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8378 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308379 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008380 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308381 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07008382 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008383
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008384 pScanInfo = &pHddCtx->scan_info;
8385
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308386 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8387 __func__, hdd_device_modetoString(pAdapter->device_mode),
8388 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008389
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308390 ret = wlan_hdd_scan_abort(pAdapter);
8391
Girish Gowli4bf7a632014-06-12 13:42:11 +05308392 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07008393 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308394 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8395 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308396
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308397 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07008398 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308399 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8400 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08008401
Jeff Johnsone7245742012-09-05 17:12:55 -07008402 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308403 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07008404 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308405 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008406 }
8407
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05308408 /* Delete all associated STAs before stopping AP/P2P GO */
8409 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05308410 hdd_hostapd_stop(dev);
8411
Jeff Johnson295189b2012-06-20 16:38:30 -07008412 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008413 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008414 )
8415 {
8416 beacon_data_t *old;
8417
8418 old = pAdapter->sessionCtx.ap.beacon;
8419
8420 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308421 {
8422 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8423 FL("session(%d) beacon data points to NULL"),
8424 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008425 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308426 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008427
Jeff Johnson295189b2012-06-20 16:38:30 -07008428 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008429
8430 mutex_lock(&pHddCtx->sap_lock);
8431 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8432 {
Jeff Johnson4416a782013-03-25 14:17:50 -07008433 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008434 {
8435 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8436
8437 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
8438
8439 if (!VOS_IS_STATUS_SUCCESS(status))
8440 {
8441 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008442 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008443 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308444 }
8445 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008446 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05308447 /* BSS stopped, clear the active sessions for this device mode */
8448 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008449 }
8450 mutex_unlock(&pHddCtx->sap_lock);
8451
8452 if(status != VOS_STATUS_SUCCESS)
8453 {
8454 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008455 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008456 return -EINVAL;
8457 }
8458
Jeff Johnson4416a782013-03-25 14:17:50 -07008459 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07008460 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
8461 ==eHAL_STATUS_FAILURE)
8462 {
8463 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008464 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008465 }
8466
Jeff Johnson4416a782013-03-25 14:17:50 -07008467 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07008468 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8469 eANI_BOOLEAN_FALSE) )
8470 {
8471 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008472 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008473 }
8474
8475 // Reset WNI_CFG_PROBE_RSP Flags
8476 wlan_hdd_reset_prob_rspies(pAdapter);
8477
8478 pAdapter->sessionCtx.ap.beacon = NULL;
8479 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008480#ifdef WLAN_FEATURE_P2P_DEBUG
8481 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
8482 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
8483 {
8484 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
8485 "GO got removed");
8486 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
8487 }
8488#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008489 }
8490 EXIT();
8491 return status;
8492}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008493
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308494#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8495static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
8496 struct net_device *dev)
8497{
8498 int ret;
8499
8500 vos_ssr_protect(__func__);
8501 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
8502 vos_ssr_unprotect(__func__);
8503
8504 return ret;
8505}
8506#else
8507static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
8508 struct net_device *dev)
8509{
8510 int ret;
8511
8512 vos_ssr_protect(__func__);
8513 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
8514 vos_ssr_unprotect(__func__);
8515
8516 return ret;
8517}
8518#endif
8519
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008520#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
8521
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308522static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308523 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008524 struct cfg80211_ap_settings *params)
8525{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308526 hdd_adapter_t *pAdapter;
8527 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308528 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008529
8530 ENTER();
8531
Girish Gowlib143d7a2015-02-18 19:39:55 +05308532 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008533 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308534 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05308535 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308536 return -ENODEV;
8537 }
8538
8539 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8540 if (NULL == pAdapter)
8541 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308542 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308543 "%s: HDD adapter is Null", __func__);
8544 return -ENODEV;
8545 }
8546
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308547 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8548 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
8549 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308550 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
8551 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308552 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308553 "%s: HDD adapter magic is invalid", __func__);
8554 return -ENODEV;
8555 }
8556
8557 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308558 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308559 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308560 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308561 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308562 }
8563
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308564 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
8565 __func__, hdd_device_modetoString(pAdapter->device_mode),
8566 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308567
8568 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008569 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008570 )
8571 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308572 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008573
8574 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308575
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008576 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308577 {
8578 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
8579 FL("already beacon info added to session(%d)"),
8580 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008581 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308582 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008583
Girish Gowlib143d7a2015-02-18 19:39:55 +05308584#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8585 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
8586 &new,
8587 &params->beacon);
8588#else
8589 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
8590 &new,
8591 &params->beacon,
8592 params->dtim_period);
8593#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008594
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308595 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008596 {
8597 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308598 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008599 return -EINVAL;
8600 }
8601 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08008602#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07008603 wlan_hdd_cfg80211_set_channel(wiphy, dev,
8604#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
8605 params->channel, params->channel_type);
8606#else
8607 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
8608#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08008609#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008610 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308611 params->ssid_len, params->hidden_ssid,
8612 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008613 }
8614
8615 EXIT();
8616 return status;
8617}
8618
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308619static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
8620 struct net_device *dev,
8621 struct cfg80211_ap_settings *params)
8622{
8623 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008624
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308625 vos_ssr_protect(__func__);
8626 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
8627 vos_ssr_unprotect(__func__);
8628
8629 return ret;
8630}
8631
8632static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008633 struct net_device *dev,
8634 struct cfg80211_beacon_data *params)
8635{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308636 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308637 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308638 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008639
8640 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308641
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308642 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8643 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
8644 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08008645 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008646 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308647
8648 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8649 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308650 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008651 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308652 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008653 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008654
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308655 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008656 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308657 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008658 {
8659 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308660
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008661 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308662
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008663 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308664 {
8665 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8666 FL("session(%d) beacon data points to NULL"),
8667 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008668 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308669 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008670
8671 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
8672
8673 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308674 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008675 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008676 return -EINVAL;
8677 }
8678
8679 pAdapter->sessionCtx.ap.beacon = new;
8680
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308681 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
8682 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008683 }
8684
8685 EXIT();
8686 return status;
8687}
8688
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308689static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8690 struct net_device *dev,
8691 struct cfg80211_beacon_data *params)
8692{
8693 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008694
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308695 vos_ssr_protect(__func__);
8696 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
8697 vos_ssr_unprotect(__func__);
8698
8699 return ret;
8700}
8701
8702#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008703
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308704static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008705 struct net_device *dev,
8706 struct bss_parameters *params)
8707{
8708 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308709 hdd_context_t *pHddCtx;
8710 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008711
8712 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308713
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308714 if (NULL == pAdapter)
8715 {
8716 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8717 "%s: HDD adapter is Null", __func__);
8718 return -ENODEV;
8719 }
8720 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308721 ret = wlan_hdd_validate_context(pHddCtx);
8722 if (0 != ret)
8723 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308724 return ret;
8725 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308726 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8727 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
8728 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308729 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8730 __func__, hdd_device_modetoString(pAdapter->device_mode),
8731 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008732
8733 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008734 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308735 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008736 {
8737 /* ap_isolate == -1 means that in change bss, upper layer doesn't
8738 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308739 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07008740 {
8741 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308742 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008743 }
8744
8745 EXIT();
8746 return 0;
8747}
8748
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308749static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
8750 struct net_device *dev,
8751 struct bss_parameters *params)
8752{
8753 int ret;
8754
8755 vos_ssr_protect(__func__);
8756 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
8757 vos_ssr_unprotect(__func__);
8758
8759 return ret;
8760}
Kiet Lam10841362013-11-01 11:36:50 +05308761/* FUNCTION: wlan_hdd_change_country_code_cd
8762* to wait for contry code completion
8763*/
8764void* wlan_hdd_change_country_code_cb(void *pAdapter)
8765{
8766 hdd_adapter_t *call_back_pAdapter = pAdapter;
8767 complete(&call_back_pAdapter->change_country_code);
8768 return NULL;
8769}
8770
Jeff Johnson295189b2012-06-20 16:38:30 -07008771/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308772 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07008773 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
8774 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308775int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008776 struct net_device *ndev,
8777 enum nl80211_iftype type,
8778 u32 *flags,
8779 struct vif_params *params
8780 )
8781{
8782 struct wireless_dev *wdev;
8783 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008784 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07008785 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008786 tCsrRoamProfile *pRoamProfile = NULL;
8787 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308788 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008789 eMib_dot11DesiredBssType connectedBssType;
8790 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308791 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008792
8793 ENTER();
8794
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308795 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008796 {
8797 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8798 "%s: Adapter context is null", __func__);
8799 return VOS_STATUS_E_FAILURE;
8800 }
8801
8802 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8803 if (!pHddCtx)
8804 {
8805 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8806 "%s: HDD context is null", __func__);
8807 return VOS_STATUS_E_FAILURE;
8808 }
8809
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308810 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8811 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
8812 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308813 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308814 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07008815 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308816 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008817 }
8818
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308819 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8820 __func__, hdd_device_modetoString(pAdapter->device_mode),
8821 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008822
Agarwal Ashish51325b52014-06-16 16:50:49 +05308823 if (vos_max_concurrent_connections_reached()) {
8824 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8825 return -EINVAL;
8826 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308827 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07008828 wdev = ndev->ieee80211_ptr;
8829
8830#ifdef WLAN_BTAMP_FEATURE
8831 if((NL80211_IFTYPE_P2P_CLIENT == type)||
8832 (NL80211_IFTYPE_ADHOC == type)||
8833 (NL80211_IFTYPE_AP == type)||
8834 (NL80211_IFTYPE_P2P_GO == type))
8835 {
8836 pHddCtx->isAmpAllowed = VOS_FALSE;
8837 // stop AMP traffic
8838 status = WLANBAP_StopAmp();
8839 if(VOS_STATUS_SUCCESS != status )
8840 {
8841 pHddCtx->isAmpAllowed = VOS_TRUE;
8842 hddLog(VOS_TRACE_LEVEL_FATAL,
8843 "%s: Failed to stop AMP", __func__);
8844 return -EINVAL;
8845 }
8846 }
8847#endif //WLAN_BTAMP_FEATURE
8848 /* Reset the current device mode bit mask*/
8849 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8850
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +05308851 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
8852 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
8853 (type == NL80211_IFTYPE_P2P_GO)))
8854 {
8855 /* Notify Mode change in case of concurrency.
8856 * Below function invokes TDLS teardown Functionality Since TDLS is
8857 * not Supported in case of concurrency i.e Once P2P session
8858 * is detected disable offchannel and teardown TDLS links
8859 */
8860 hddLog(LOG1,
8861 FL("Device mode = %d Interface type = %d"),
8862 pAdapter->device_mode, type);
8863 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
8864 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +05308865
Jeff Johnson295189b2012-06-20 16:38:30 -07008866 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008867 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07008868 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008869 )
8870 {
8871 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008872 if (!pWextState)
8873 {
8874 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8875 "%s: pWextState is null", __func__);
8876 return VOS_STATUS_E_FAILURE;
8877 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008878 pRoamProfile = &pWextState->roamProfile;
8879 LastBSSType = pRoamProfile->BSSType;
8880
8881 switch (type)
8882 {
8883 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008884 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008885 hddLog(VOS_TRACE_LEVEL_INFO,
8886 "%s: setting interface Type to INFRASTRUCTURE", __func__);
8887 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008888#ifdef WLAN_FEATURE_11AC
8889 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
8890 {
8891 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
8892 }
8893#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308894 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07008895 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008896 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008897 //Check for sub-string p2p to confirm its a p2p interface
8898 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308899 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +05308900#ifdef FEATURE_WLAN_TDLS
8901 mutex_lock(&pHddCtx->tdls_lock);
8902 wlan_hdd_tdls_exit(pAdapter, TRUE);
8903 mutex_unlock(&pHddCtx->tdls_lock);
8904#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008905 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8906 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8907 }
8908 else
8909 {
8910 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008911 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008912 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008913 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05308914
Jeff Johnson295189b2012-06-20 16:38:30 -07008915 case NL80211_IFTYPE_ADHOC:
8916 hddLog(VOS_TRACE_LEVEL_INFO,
8917 "%s: setting interface Type to ADHOC", __func__);
8918 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
8919 pRoamProfile->phyMode =
8920 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07008921 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008922 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +05308923 hdd_set_ibss_ops( pAdapter );
8924 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +05308925
8926 status = hdd_sta_id_hash_attach(pAdapter);
8927 if (VOS_STATUS_SUCCESS != status) {
8928 hddLog(VOS_TRACE_LEVEL_ERROR,
8929 FL("Failed to initialize hash for IBSS"));
8930 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008931 break;
8932
8933 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008934 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008935 {
8936 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8937 "%s: setting interface Type to %s", __func__,
8938 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
8939
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008940 //Cancel any remain on channel for GO mode
8941 if (NL80211_IFTYPE_P2P_GO == type)
8942 {
8943 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
8944 }
Mohit Khanna0f232092012-09-11 14:46:08 -07008945 if (NL80211_IFTYPE_AP == type)
8946 {
8947 /* As Loading WLAN Driver one interface being created for p2p device
8948 * address. This will take one HW STA and the max number of clients
8949 * that can connect to softAP will be reduced by one. so while changing
8950 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
8951 * interface as it is not required in SoftAP mode.
8952 */
8953
8954 // Get P2P Adapter
8955 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
8956
8957 if (pP2pAdapter)
8958 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308959 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05308960 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07008961 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
8962 }
8963 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05308964 //Disable IMPS & BMPS for SAP/GO
8965 if(VOS_STATUS_E_FAILURE ==
8966 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
8967 {
8968 //Fail to Exit BMPS
8969 VOS_ASSERT(0);
8970 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05308971
8972 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
8973
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308974#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07008975
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308976 /* A Mutex Lock is introduced while changing the mode to
8977 * protect the concurrent access for the Adapters by TDLS
8978 * module.
8979 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308980 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308981#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008982 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05308983 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008984 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07008985 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8986 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308987#ifdef FEATURE_WLAN_TDLS
8988 mutex_unlock(&pHddCtx->tdls_lock);
8989#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008990 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
8991 (pConfig->apRandomBssidEnabled))
8992 {
8993 /* To meet Android requirements create a randomized
8994 MAC address of the form 02:1A:11:Fx:xx:xx */
8995 get_random_bytes(&ndev->dev_addr[3], 3);
8996 ndev->dev_addr[0] = 0x02;
8997 ndev->dev_addr[1] = 0x1A;
8998 ndev->dev_addr[2] = 0x11;
8999 ndev->dev_addr[3] |= 0xF0;
9000 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
9001 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08009002 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
9003 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07009004 }
9005
Jeff Johnson295189b2012-06-20 16:38:30 -07009006 hdd_set_ap_ops( pAdapter->dev );
9007
Kiet Lam10841362013-11-01 11:36:50 +05309008 /* This is for only SAP mode where users can
9009 * control country through ini.
9010 * P2P GO follows station country code
9011 * acquired during the STA scanning. */
9012 if((NL80211_IFTYPE_AP == type) &&
9013 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
9014 {
9015 int status = 0;
9016 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
9017 "%s: setting country code from INI ", __func__);
9018 init_completion(&pAdapter->change_country_code);
9019 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
9020 (void *)(tSmeChangeCountryCallback)
9021 wlan_hdd_change_country_code_cb,
9022 pConfig->apCntryCode, pAdapter,
9023 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05309024 eSIR_FALSE,
9025 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05309026 if (eHAL_STATUS_SUCCESS == status)
9027 {
9028 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309029 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05309030 &pAdapter->change_country_code,
9031 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309032 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05309033 {
9034 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309035 FL("SME Timed out while setting country code %ld"),
9036 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08009037
9038 if (pHddCtx->isLogpInProgress)
9039 {
9040 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9041 "%s: LOGP in Progress. Ignore!!!", __func__);
9042 return -EAGAIN;
9043 }
Kiet Lam10841362013-11-01 11:36:50 +05309044 }
9045 }
9046 else
9047 {
9048 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08009049 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05309050 return -EINVAL;
9051 }
9052 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009053 status = hdd_init_ap_mode(pAdapter);
9054 if(status != VOS_STATUS_SUCCESS)
9055 {
9056 hddLog(VOS_TRACE_LEVEL_FATAL,
9057 "%s: Error initializing the ap mode", __func__);
9058 return -EINVAL;
9059 }
9060 hdd_set_conparam(1);
9061
Nirav Shah7e3c8132015-06-22 23:51:42 +05309062 status = hdd_sta_id_hash_attach(pAdapter);
9063 if (VOS_STATUS_SUCCESS != status)
9064 {
9065 hddLog(VOS_TRACE_LEVEL_ERROR,
9066 FL("Failed to initialize hash for AP"));
9067 return -EINVAL;
9068 }
9069
Jeff Johnson295189b2012-06-20 16:38:30 -07009070 /*interface type changed update in wiphy structure*/
9071 if(wdev)
9072 {
9073 wdev->iftype = type;
9074 pHddCtx->change_iface = type;
9075 }
9076 else
9077 {
9078 hddLog(VOS_TRACE_LEVEL_ERROR,
9079 "%s: ERROR !!!! Wireless dev is NULL", __func__);
9080 return -EINVAL;
9081 }
9082 goto done;
9083 }
9084
9085 default:
9086 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
9087 __func__);
9088 return -EOPNOTSUPP;
9089 }
9090 }
9091 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009092 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07009093 )
9094 {
9095 switch(type)
9096 {
9097 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07009098 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07009099 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05309100
9101 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309102#ifdef FEATURE_WLAN_TDLS
9103
9104 /* A Mutex Lock is introduced while changing the mode to
9105 * protect the concurrent access for the Adapters by TDLS
9106 * module.
9107 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309108 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309109#endif
c_hpothu002231a2015-02-05 14:58:51 +05309110 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07009111 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08009112 //Check for sub-string p2p to confirm its a p2p interface
9113 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08009114 {
9115 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
9116 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
9117 }
9118 else
9119 {
9120 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07009121 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08009122 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009123 hdd_set_conparam(0);
9124 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07009125 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
9126 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309127#ifdef FEATURE_WLAN_TDLS
9128 mutex_unlock(&pHddCtx->tdls_lock);
9129#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05309130 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07009131 if( VOS_STATUS_SUCCESS != status )
9132 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07009133 /* In case of JB, for P2P-GO, only change interface will be called,
9134 * This is the right place to enable back bmps_imps()
9135 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05309136 if (pHddCtx->hdd_wlan_suspended)
9137 {
9138 hdd_set_pwrparams(pHddCtx);
9139 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009140 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07009141 goto done;
9142 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07009143 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07009144 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07009145 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
9146 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07009147 goto done;
9148 default:
9149 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
9150 __func__);
9151 return -EOPNOTSUPP;
9152
9153 }
9154
9155 }
9156 else
9157 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309158 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
9159 __func__, hdd_device_modetoString(pAdapter->device_mode),
9160 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009161 return -EOPNOTSUPP;
9162 }
9163
9164
9165 if(pRoamProfile)
9166 {
9167 if ( LastBSSType != pRoamProfile->BSSType )
9168 {
9169 /*interface type changed update in wiphy structure*/
9170 wdev->iftype = type;
9171
9172 /*the BSS mode changed, We need to issue disconnect
9173 if connected or in IBSS disconnect state*/
9174 if ( hdd_connGetConnectedBssType(
9175 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
9176 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
9177 {
9178 /*need to issue a disconnect to CSR.*/
9179 INIT_COMPLETION(pAdapter->disconnect_comp_var);
9180 if( eHAL_STATUS_SUCCESS ==
9181 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
9182 pAdapter->sessionId,
9183 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
9184 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309185 ret = wait_for_completion_interruptible_timeout(
9186 &pAdapter->disconnect_comp_var,
9187 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
9188 if (ret <= 0)
9189 {
9190 hddLog(VOS_TRACE_LEVEL_ERROR,
9191 FL("wait on disconnect_comp_var failed %ld"), ret);
9192 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009193 }
9194 }
9195 }
9196 }
9197
9198done:
9199 /*set bitmask based on updated value*/
9200 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07009201
9202 /* Only STA mode support TM now
9203 * all other mode, TM feature should be disabled */
9204 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
9205 (~VOS_STA & pHddCtx->concurrency_mode) )
9206 {
9207 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
9208 }
9209
Jeff Johnson295189b2012-06-20 16:38:30 -07009210#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309211 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05309212 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07009213 {
9214 //we are ok to do AMP
9215 pHddCtx->isAmpAllowed = VOS_TRUE;
9216 }
9217#endif //WLAN_BTAMP_FEATURE
9218 EXIT();
9219 return 0;
9220}
9221
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05309222/*
9223 * FUNCTION: wlan_hdd_cfg80211_change_iface
9224 * wrapper function to protect the actual implementation from SSR.
9225 */
9226int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
9227 struct net_device *ndev,
9228 enum nl80211_iftype type,
9229 u32 *flags,
9230 struct vif_params *params
9231 )
9232{
9233 int ret;
9234
9235 vos_ssr_protect(__func__);
9236 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
9237 vos_ssr_unprotect(__func__);
9238
9239 return ret;
9240}
9241
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009242#ifdef FEATURE_WLAN_TDLS
9243static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309244 struct net_device *dev,
9245#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
9246 const u8 *mac,
9247#else
9248 u8 *mac,
9249#endif
9250 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009251{
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009252 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009253 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309254 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309255 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05309256 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309257 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009258
9259 ENTER();
9260
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05309261 if (!dev) {
9262 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
9263 return -EINVAL;
9264 }
9265
9266 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9267 if (!pAdapter) {
9268 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
9269 return -EINVAL;
9270 }
9271
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309272 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009273 {
9274 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9275 "Invalid arguments");
9276 return -EINVAL;
9277 }
Hoonki Lee27511902013-03-14 18:19:06 -07009278
9279 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
9280 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
9281 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -07009283 "%s: TDLS mode is disabled OR not enabled in FW."
9284 MAC_ADDRESS_STR " Request declined.",
9285 __func__, MAC_ADDR_ARRAY(mac));
9286 return -ENOTSUPP;
9287 }
9288
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009289 if (pHddCtx->isLogpInProgress)
9290 {
9291 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9292 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05309293 wlan_hdd_tdls_set_link_status(pAdapter,
9294 mac,
9295 eTDLS_LINK_IDLE,
9296 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009297 return -EBUSY;
9298 }
9299
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309300 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05309301 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009302
9303 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009305 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
9306 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309307 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009308 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009309 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309310 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009311
9312 /* in add station, we accept existing valid staId if there is */
9313 if ((0 == update) &&
9314 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
9315 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009316 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309317 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009318 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009319 " link_status %d. staId %d. add station ignored.",
9320 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
9321 return 0;
9322 }
9323 /* in change station, we accept only when staId is valid */
9324 if ((1 == update) &&
9325 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
9326 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
9327 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309328 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009329 "%s: " MAC_ADDRESS_STR
9330 " link status %d. staId %d. change station %s.",
9331 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
9332 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
9333 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009334 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009335
9336 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +05309337 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009338 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009339 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9340 "%s: " MAC_ADDRESS_STR
9341 " TDLS setup is ongoing. Request declined.",
9342 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07009343 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009344 }
9345
9346 /* first to check if we reached to maximum supported TDLS peer.
9347 TODO: for now, return -EPERM looks working fine,
9348 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309349 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
9350 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009351 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009352 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9353 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309354 " TDLS Max peer already connected. Request declined."
9355 " Num of peers (%d), Max allowed (%d).",
9356 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
9357 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009358 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009359 }
9360 else
9361 {
9362 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309363 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009364 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009365 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009366 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9367 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
9368 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009369 return -EPERM;
9370 }
9371 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009372 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05309373 wlan_hdd_tdls_set_link_status(pAdapter,
9374 mac,
9375 eTDLS_LINK_CONNECTING,
9376 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009377
Jeff Johnsond75fe012013-04-06 10:53:06 -07009378 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309379 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009380 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309381 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009382 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07009383 if(StaParams->htcap_present)
9384 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009386 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309387 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009388 "ht_capa->extended_capabilities: %0x",
9389 StaParams->HTCap.extendedHtCapInfo);
9390 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309391 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009392 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309393 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009394 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07009395 if(StaParams->vhtcap_present)
9396 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009398 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
9399 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
9400 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
9401 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009402 {
9403 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009404 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009405 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309406 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009407 "[%d]: %x ", i, StaParams->supported_rates[i]);
9408 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07009409 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309410 else if ((1 == update) && (NULL == StaParams))
9411 {
9412 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9413 "%s : update is true, but staParams is NULL. Error!", __func__);
9414 return -EPERM;
9415 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009416
9417 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
9418
9419 if (!update)
9420 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309421 /*Before adding sta make sure that device exited from BMPS*/
9422 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
9423 {
9424 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9425 "%s: Adding tdls peer sta. Disable BMPS", __func__);
9426 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
9427 if (status != VOS_STATUS_SUCCESS) {
9428 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
9429 }
9430 }
9431
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309432 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009433 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309434 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309435 hddLog(VOS_TRACE_LEVEL_ERROR,
9436 FL("Failed to add TDLS peer STA. Enable Bmps"));
9437 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309438 return -EPERM;
9439 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009440 }
9441 else
9442 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309443 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009444 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309445 if (ret != eHAL_STATUS_SUCCESS) {
9446 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
9447 return -EPERM;
9448 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009449 }
9450
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309451 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009452 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
9453
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309454 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009455 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009456 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309457 "%s: timeout waiting for tdls add station indication %ld",
9458 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009459 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009460 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309461
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009462 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
9463 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009464 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009465 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009466 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009467 }
9468
9469 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07009470
9471error:
Atul Mittal115287b2014-07-08 13:26:33 +05309472 wlan_hdd_tdls_set_link_status(pAdapter,
9473 mac,
9474 eTDLS_LINK_IDLE,
9475 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009476 return -EPERM;
9477
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009478}
9479#endif
9480
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309481static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009482 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309483#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
9484 const u8 *mac,
9485#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009486 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309487#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009488 struct station_parameters *params)
9489{
9490 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309491 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309492 hdd_context_t *pHddCtx;
9493 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009494 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309495 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009496#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009497 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009498 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309499 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009500#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009501
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309502 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309503
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309504 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +05309505 if ((NULL == pAdapter))
9506 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309507 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309508 "invalid adapter ");
9509 return -EINVAL;
9510 }
9511
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309512 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9513 TRACE_CODE_HDD_CHANGE_STATION,
9514 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05309515 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05309516
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309517 ret = wlan_hdd_validate_context(pHddCtx);
9518 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05309519 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309520 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309521 }
9522
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309523 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9524
9525 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009526 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309527 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9528 "invalid HDD station context");
9529 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009530 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009531 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
9532
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009533 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
9534 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07009535 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009536 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07009537 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309538 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07009539 WLANTL_STA_AUTHENTICATED);
9540
Gopichand Nakkala29149562013-05-10 21:43:41 +05309541 if (status != VOS_STATUS_SUCCESS)
9542 {
9543 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9544 "%s: Not able to change TL state to AUTHENTICATED", __func__);
9545 return -EINVAL;
9546 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009547 }
9548 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07009549 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
9550 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309551#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009552 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
9553 StaParams.capability = params->capability;
9554 StaParams.uapsd_queues = params->uapsd_queues;
9555 StaParams.max_sp = params->max_sp;
9556
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309557 /* Convert (first channel , number of channels) tuple to
9558 * the total list of channels. This goes with the assumption
9559 * that if the first channel is < 14, then the next channels
9560 * are an incremental of 1 else an incremental of 4 till the number
9561 * of channels.
9562 */
9563 if (0 != params->supported_channels_len) {
9564 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
9565 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
9566 {
9567 int wifi_chan_index;
9568 StaParams.supported_channels[j] = params->supported_channels[i];
9569 wifi_chan_index =
9570 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
9571 no_of_channels = params->supported_channels[i+1];
9572 for(k=1; k <= no_of_channels; k++)
9573 {
9574 StaParams.supported_channels[j+1] =
9575 StaParams.supported_channels[j] + wifi_chan_index;
9576 j+=1;
9577 }
9578 }
9579 StaParams.supported_channels_len = j;
9580 }
9581 vos_mem_copy(StaParams.supported_oper_classes,
9582 params->supported_oper_classes,
9583 params->supported_oper_classes_len);
9584 StaParams.supported_oper_classes_len =
9585 params->supported_oper_classes_len;
9586
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009587 if (0 != params->ext_capab_len)
9588 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
9589 sizeof(StaParams.extn_capability));
9590
9591 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07009592 {
9593 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009594 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07009595 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009596
9597 StaParams.supported_rates_len = params->supported_rates_len;
9598
9599 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
9600 * The supported_rates array , for all the structures propogating till Add Sta
9601 * to the firmware has to be modified , if the supplicant (ieee80211) is
9602 * modified to send more rates.
9603 */
9604
9605 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
9606 */
9607 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
9608 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
9609
9610 if (0 != StaParams.supported_rates_len) {
9611 int i = 0;
9612 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
9613 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009615 "Supported Rates with Length %d", StaParams.supported_rates_len);
9616 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009617 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009618 "[%d]: %0x", i, StaParams.supported_rates[i]);
9619 }
9620
9621 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07009622 {
9623 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009624 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07009625 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009626
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009627 if (0 != params->ext_capab_len ) {
9628 /*Define A Macro : TODO Sunil*/
9629 if ((1<<4) & StaParams.extn_capability[3]) {
9630 isBufSta = 1;
9631 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309632 /* TDLS Channel Switching Support */
9633 if ((1<<6) & StaParams.extn_capability[3]) {
9634 isOffChannelSupported = 1;
9635 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009636 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309637 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
9638 &StaParams, isBufSta,
9639 isOffChannelSupported);
9640
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309641 if (VOS_STATUS_SUCCESS != status) {
9642 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9643 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
9644 return -EINVAL;
9645 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009646 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
9647
9648 if (VOS_STATUS_SUCCESS != status) {
9649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9650 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
9651 return -EINVAL;
9652 }
9653 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009654#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05309655 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009656 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009657 return status;
9658}
9659
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309660#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
9661static int wlan_hdd_change_station(struct wiphy *wiphy,
9662 struct net_device *dev,
9663 const u8 *mac,
9664 struct station_parameters *params)
9665#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309666static int wlan_hdd_change_station(struct wiphy *wiphy,
9667 struct net_device *dev,
9668 u8 *mac,
9669 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309670#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309671{
9672 int ret;
9673
9674 vos_ssr_protect(__func__);
9675 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
9676 vos_ssr_unprotect(__func__);
9677
9678 return ret;
9679}
9680
Jeff Johnson295189b2012-06-20 16:38:30 -07009681/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309682 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009683 * This function is used to initialize the key information
9684 */
9685#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309686static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009687 struct net_device *ndev,
9688 u8 key_index, bool pairwise,
9689 const u8 *mac_addr,
9690 struct key_params *params
9691 )
9692#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309693static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009694 struct net_device *ndev,
9695 u8 key_index, const u8 *mac_addr,
9696 struct key_params *params
9697 )
9698#endif
9699{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009700 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07009701 tCsrRoamSetKey setKey;
9702 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309703 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009704 v_U32_t roamId= 0xFF;
9705 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009706 hdd_hostapd_state_t *pHostapdState;
9707 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009708 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309709 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009710
9711 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309712
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309713 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9714 TRACE_CODE_HDD_CFG80211_ADD_KEY,
9715 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309716 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9717 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309718 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009719 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309720 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009721 }
9722
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309723 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9724 __func__, hdd_device_modetoString(pAdapter->device_mode),
9725 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009726
9727 if (CSR_MAX_NUM_KEY <= key_index)
9728 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009729 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009730 key_index);
9731
9732 return -EINVAL;
9733 }
9734
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009735 if (CSR_MAX_KEY_LEN < params->key_len)
9736 {
9737 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
9738 params->key_len);
9739
9740 return -EINVAL;
9741 }
9742
9743 hddLog(VOS_TRACE_LEVEL_INFO,
9744 "%s: called with key index = %d & key length %d",
9745 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009746
9747 /*extract key idx, key len and key*/
9748 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9749 setKey.keyId = key_index;
9750 setKey.keyLength = params->key_len;
9751 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
9752
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009753 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009754 {
9755 case WLAN_CIPHER_SUITE_WEP40:
9756 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
9757 break;
9758
9759 case WLAN_CIPHER_SUITE_WEP104:
9760 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
9761 break;
9762
9763 case WLAN_CIPHER_SUITE_TKIP:
9764 {
9765 u8 *pKey = &setKey.Key[0];
9766 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
9767
9768 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
9769
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009770 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07009771
9772 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009773 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009774 |--------------|----------|----------|
9775 <---16bytes---><--8bytes--><--8bytes-->
9776
9777 */
9778 /*Sme expects the 32 bytes key to be in the below order
9779
9780 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009781 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009782 |--------------|----------|----------|
9783 <---16bytes---><--8bytes--><--8bytes-->
9784 */
9785 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009786 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07009787
9788 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009789 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009790
9791 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009792 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009793
9794
9795 break;
9796 }
9797
9798 case WLAN_CIPHER_SUITE_CCMP:
9799 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
9800 break;
9801
9802#ifdef FEATURE_WLAN_WAPI
9803 case WLAN_CIPHER_SUITE_SMS4:
9804 {
9805 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9806 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
9807 params->key, params->key_len);
9808 return 0;
9809 }
9810#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009811
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009812#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009813 case WLAN_CIPHER_SUITE_KRK:
9814 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
9815 break;
9816#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009817
9818#ifdef WLAN_FEATURE_11W
9819 case WLAN_CIPHER_SUITE_AES_CMAC:
9820 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07009821 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07009822#endif
9823
Jeff Johnson295189b2012-06-20 16:38:30 -07009824 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009825 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009826 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309827 status = -EOPNOTSUPP;
9828 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009829 }
9830
9831 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
9832 __func__, setKey.encType);
9833
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009834 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07009835#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9836 (!pairwise)
9837#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009838 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07009839#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009840 )
9841 {
9842 /* set group key*/
9843 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9844 "%s- %d: setting Broadcast key",
9845 __func__, __LINE__);
9846 setKey.keyDirection = eSIR_RX_ONLY;
9847 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9848 }
9849 else
9850 {
9851 /* set pairwise key*/
9852 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9853 "%s- %d: setting pairwise key",
9854 __func__, __LINE__);
9855 setKey.keyDirection = eSIR_TX_RX;
9856 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9857 }
9858 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
9859 {
9860 setKey.keyDirection = eSIR_TX_RX;
9861 /*Set the group key*/
9862 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9863 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07009864
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009865 if ( 0 != status )
9866 {
9867 hddLog(VOS_TRACE_LEVEL_ERROR,
9868 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309869 status = -EINVAL;
9870 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009871 }
9872 /*Save the keys here and call sme_RoamSetKey for setting
9873 the PTK after peer joins the IBSS network*/
9874 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
9875 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309876 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009877 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05309878 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
9879 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
9880 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009881 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009882 if( pHostapdState->bssState == BSS_START )
9883 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009884 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9885 vos_status = wlan_hdd_check_ula_done(pAdapter);
9886
9887 if ( vos_status != VOS_STATUS_SUCCESS )
9888 {
9889 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9890 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9891 __LINE__, vos_status );
9892
9893 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9894
9895 status = -EINVAL;
9896 goto end;
9897 }
9898
Jeff Johnson295189b2012-06-20 16:38:30 -07009899 status = WLANSAP_SetKeySta( pVosContext, &setKey);
9900
9901 if ( status != eHAL_STATUS_SUCCESS )
9902 {
9903 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9904 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9905 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309906 status = -EINVAL;
9907 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009908 }
9909 }
9910
9911 /* Saving WEP keys */
9912 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
9913 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
9914 {
9915 //Save the wep key in ap context. Issue setkey after the BSS is started.
9916 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9917 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
9918 }
9919 else
9920 {
9921 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009922 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009923 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
9924 }
9925 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009926 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
9927 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009928 {
9929 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9930 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9931
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309932#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9933 if (!pairwise)
9934#else
9935 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9936#endif
9937 {
9938 /* set group key*/
9939 if (pHddStaCtx->roam_info.deferKeyComplete)
9940 {
9941 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9942 "%s- %d: Perform Set key Complete",
9943 __func__, __LINE__);
9944 hdd_PerformRoamSetKeyComplete(pAdapter);
9945 }
9946 }
9947
Jeff Johnson295189b2012-06-20 16:38:30 -07009948 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
9949
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08009950 pWextState->roamProfile.Keys.defaultIndex = key_index;
9951
9952
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009953 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009954 params->key, params->key_len);
9955
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309956
Jeff Johnson295189b2012-06-20 16:38:30 -07009957 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9958
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309959 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009960 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309961 __func__, setKey.peerMac[0], setKey.peerMac[1],
9962 setKey.peerMac[2], setKey.peerMac[3],
9963 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009964 setKey.keyDirection);
9965
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009966 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +05309967
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009968 if ( vos_status != VOS_STATUS_SUCCESS )
9969 {
9970 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009971 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9972 __LINE__, vos_status );
9973
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009974 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009975
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009976 status = -EINVAL;
9977 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009978
9979 }
9980
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009981#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309982 /* The supplicant may attempt to set the PTK once pre-authentication
9983 is done. Save the key in the UMAC and include it in the ADD BSS
9984 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009985 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309986 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009987 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309988 hddLog(VOS_TRACE_LEVEL_INFO_MED,
9989 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309990 status = 0;
9991 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309992 }
9993 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
9994 {
9995 hddLog(VOS_TRACE_LEVEL_ERROR,
9996 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309997 status = -EINVAL;
9998 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009999 }
10000#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -070010001
10002 /* issue set key request to SME*/
10003 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
10004 pAdapter->sessionId, &setKey, &roamId );
10005
10006 if ( 0 != status )
10007 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010008 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010009 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
10010 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010011 status = -EINVAL;
10012 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070010013 }
10014
10015
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010016 /* in case of IBSS as there was no information available about WEP keys during
10017 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -070010018 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010019 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
10020 !( ( IW_AUTH_KEY_MGMT_802_1X
10021 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -070010022 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
10023 )
10024 &&
10025 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
10026 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
10027 )
10028 )
10029 {
10030 setKey.keyDirection = eSIR_RX_ONLY;
10031 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
10032
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010033 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070010034 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010035 __func__, setKey.peerMac[0], setKey.peerMac[1],
10036 setKey.peerMac[2], setKey.peerMac[3],
10037 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -070010038 setKey.keyDirection);
10039
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010040 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010041 pAdapter->sessionId, &setKey, &roamId );
10042
10043 if ( 0 != status )
10044 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010045 hddLog(VOS_TRACE_LEVEL_ERROR,
10046 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010047 __func__, status);
10048 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010049 status = -EINVAL;
10050 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -070010051 }
10052 }
10053 }
10054
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010055end:
10056 /* Need to clear any trace of key value in the memory.
10057 * Thus zero out the memory even though it is local
10058 * variable.
10059 */
10060 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010061 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053010062 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070010063}
10064
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010065#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10066static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
10067 struct net_device *ndev,
10068 u8 key_index, bool pairwise,
10069 const u8 *mac_addr,
10070 struct key_params *params
10071 )
10072#else
10073static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
10074 struct net_device *ndev,
10075 u8 key_index, const u8 *mac_addr,
10076 struct key_params *params
10077 )
10078#endif
10079{
10080 int ret;
10081 vos_ssr_protect(__func__);
10082#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10083 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
10084 mac_addr, params);
10085#else
10086 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
10087 params);
10088#endif
10089 vos_ssr_unprotect(__func__);
10090
10091 return ret;
10092}
10093
Jeff Johnson295189b2012-06-20 16:38:30 -070010094/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010095 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010096 * This function is used to get the key information
10097 */
10098#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010099static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010100 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010101 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010102 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070010103 const u8 *mac_addr, void *cookie,
10104 void (*callback)(void *cookie, struct key_params*)
10105 )
10106#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010107static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010108 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010109 struct net_device *ndev,
10110 u8 key_index, const u8 *mac_addr, void *cookie,
10111 void (*callback)(void *cookie, struct key_params*)
10112 )
10113#endif
10114{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010115 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010116 hdd_wext_state_t *pWextState = NULL;
10117 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010118 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010119 hdd_context_t *pHddCtx;
10120 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010121
10122 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010123
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010124 if (NULL == pAdapter)
10125 {
10126 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10127 "%s: HDD adapter is Null", __func__);
10128 return -ENODEV;
10129 }
10130
10131 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10132 ret = wlan_hdd_validate_context(pHddCtx);
10133 if (0 != ret)
10134 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053010135 return ret;
10136 }
10137
10138 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10139 pRoamProfile = &(pWextState->roamProfile);
10140
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010141 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10142 __func__, hdd_device_modetoString(pAdapter->device_mode),
10143 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010144
Jeff Johnson295189b2012-06-20 16:38:30 -070010145 memset(&params, 0, sizeof(params));
10146
10147 if (CSR_MAX_NUM_KEY <= key_index)
10148 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010149 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070010150 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010151 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010152
10153 switch(pRoamProfile->EncryptionType.encryptionType[0])
10154 {
10155 case eCSR_ENCRYPT_TYPE_NONE:
10156 params.cipher = IW_AUTH_CIPHER_NONE;
10157 break;
10158
10159 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
10160 case eCSR_ENCRYPT_TYPE_WEP40:
10161 params.cipher = WLAN_CIPHER_SUITE_WEP40;
10162 break;
10163
10164 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
10165 case eCSR_ENCRYPT_TYPE_WEP104:
10166 params.cipher = WLAN_CIPHER_SUITE_WEP104;
10167 break;
10168
10169 case eCSR_ENCRYPT_TYPE_TKIP:
10170 params.cipher = WLAN_CIPHER_SUITE_TKIP;
10171 break;
10172
10173 case eCSR_ENCRYPT_TYPE_AES:
10174 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
10175 break;
10176
10177 default:
10178 params.cipher = IW_AUTH_CIPHER_NONE;
10179 break;
10180 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010181
c_hpothuaaf19692014-05-17 17:01:48 +053010182 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10183 TRACE_CODE_HDD_CFG80211_GET_KEY,
10184 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010185
Jeff Johnson295189b2012-06-20 16:38:30 -070010186 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
10187 params.seq_len = 0;
10188 params.seq = NULL;
10189 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
10190 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010191 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010192 return 0;
10193}
10194
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010195#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10196static int wlan_hdd_cfg80211_get_key(
10197 struct wiphy *wiphy,
10198 struct net_device *ndev,
10199 u8 key_index, bool pairwise,
10200 const u8 *mac_addr, void *cookie,
10201 void (*callback)(void *cookie, struct key_params*)
10202 )
10203#else
10204static int wlan_hdd_cfg80211_get_key(
10205 struct wiphy *wiphy,
10206 struct net_device *ndev,
10207 u8 key_index, const u8 *mac_addr, void *cookie,
10208 void (*callback)(void *cookie, struct key_params*)
10209 )
10210#endif
10211{
10212 int ret;
10213
10214 vos_ssr_protect(__func__);
10215#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10216 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
10217 mac_addr, cookie, callback);
10218#else
10219 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
10220 callback);
10221#endif
10222 vos_ssr_unprotect(__func__);
10223
10224 return ret;
10225}
10226
Jeff Johnson295189b2012-06-20 16:38:30 -070010227/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010228 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010229 * This function is used to delete the key information
10230 */
10231#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010232static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010233 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010234 u8 key_index,
10235 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070010236 const u8 *mac_addr
10237 )
10238#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010239static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010240 struct net_device *ndev,
10241 u8 key_index,
10242 const u8 *mac_addr
10243 )
10244#endif
10245{
10246 int status = 0;
10247
10248 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010249 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070010250 //it is observed that this is invalidating peer
10251 //key index whenever re-key is done. This is affecting data link.
10252 //It should be ok to ignore del_key.
10253#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010254 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
10255 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010256 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
10257 tCsrRoamSetKey setKey;
10258 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010259
Jeff Johnson295189b2012-06-20 16:38:30 -070010260 ENTER();
10261
10262 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
10263 __func__,pAdapter->device_mode);
10264
10265 if (CSR_MAX_NUM_KEY <= key_index)
10266 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010267 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010268 key_index);
10269
10270 return -EINVAL;
10271 }
10272
10273 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
10274 setKey.keyId = key_index;
10275
10276 if (mac_addr)
10277 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
10278 else
10279 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
10280
10281 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
10282
10283 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010284 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010285 )
10286 {
10287
10288 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070010289 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10290 if( pHostapdState->bssState == BSS_START)
10291 {
10292 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010293
Jeff Johnson295189b2012-06-20 16:38:30 -070010294 if ( status != eHAL_STATUS_SUCCESS )
10295 {
10296 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10297 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
10298 __LINE__, status );
10299 }
10300 }
10301 }
10302 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010303 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070010304 )
10305 {
10306 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10307
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010308 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
10309
10310 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070010311 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010312 __func__, setKey.peerMac[0], setKey.peerMac[1],
10313 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070010314 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010315 if(pAdapter->sessionCtx.station.conn_info.connState ==
10316 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070010317 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010318 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010319 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010320
Jeff Johnson295189b2012-06-20 16:38:30 -070010321 if ( 0 != status )
10322 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010323 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010324 "%s: sme_RoamSetKey failure, returned %d",
10325 __func__, status);
10326 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
10327 return -EINVAL;
10328 }
10329 }
10330 }
10331#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010332 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010333 return status;
10334}
10335
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010336#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10337static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
10338 struct net_device *ndev,
10339 u8 key_index,
10340 bool pairwise,
10341 const u8 *mac_addr
10342 )
10343#else
10344static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
10345 struct net_device *ndev,
10346 u8 key_index,
10347 const u8 *mac_addr
10348 )
10349#endif
10350{
10351 int ret;
10352
10353 vos_ssr_protect(__func__);
10354#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10355 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
10356 mac_addr);
10357#else
10358 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
10359#endif
10360 vos_ssr_unprotect(__func__);
10361
10362 return ret;
10363}
10364
Jeff Johnson295189b2012-06-20 16:38:30 -070010365/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010366 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010367 * This function is used to set the default tx key index
10368 */
10369#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010370static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010371 struct net_device *ndev,
10372 u8 key_index,
10373 bool unicast, bool multicast)
10374#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010375static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010376 struct net_device *ndev,
10377 u8 key_index)
10378#endif
10379{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010380 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010381 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010382 hdd_wext_state_t *pWextState;
10383 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010384 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010385
10386 ENTER();
10387
Gopichand Nakkala29149562013-05-10 21:43:41 +053010388 if ((NULL == pAdapter))
10389 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010391 "invalid adapter");
10392 return -EINVAL;
10393 }
10394
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010395 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10396 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
10397 pAdapter->sessionId, key_index));
10398
Gopichand Nakkala29149562013-05-10 21:43:41 +053010399 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10400 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10401
10402 if ((NULL == pWextState) || (NULL == pHddStaCtx))
10403 {
10404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10405 "invalid Wext state or HDD context");
10406 return -EINVAL;
10407 }
10408
Arif Hussain6d2a3322013-11-17 19:50:10 -080010409 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010410 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010411
Jeff Johnson295189b2012-06-20 16:38:30 -070010412 if (CSR_MAX_NUM_KEY <= key_index)
10413 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010414 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010415 key_index);
10416
10417 return -EINVAL;
10418 }
10419
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010420 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10421 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010422 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010423 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010424 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010425 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010426
Jeff Johnson295189b2012-06-20 16:38:30 -070010427 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010428 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010429 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010430 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053010431 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080010432 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010433 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080010434 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070010435 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010436 {
10437 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070010438 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010439
Jeff Johnson295189b2012-06-20 16:38:30 -070010440 tCsrRoamSetKey setKey;
10441 v_U32_t roamId= 0xFF;
10442 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010443
10444 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010445 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010446
Jeff Johnson295189b2012-06-20 16:38:30 -070010447 Keys->defaultIndex = (u8)key_index;
10448 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
10449 setKey.keyId = key_index;
10450 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010451
10452 vos_mem_copy(&setKey.Key[0],
10453 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010454 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010455
Gopichand Nakkala29149562013-05-10 21:43:41 +053010456 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010457
10458 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070010459 &pHddStaCtx->conn_info.bssId[0],
10460 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010461
Gopichand Nakkala29149562013-05-10 21:43:41 +053010462 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
10463 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
10464 eCSR_ENCRYPT_TYPE_WEP104)
10465 {
10466 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
10467 even though ap is configured for WEP-40 encryption. In this canse the key length
10468 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
10469 type(104) and switching encryption type to 40*/
10470 pWextState->roamProfile.EncryptionType.encryptionType[0] =
10471 eCSR_ENCRYPT_TYPE_WEP40;
10472 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
10473 eCSR_ENCRYPT_TYPE_WEP40;
10474 }
10475
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010476 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070010477 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010478
Jeff Johnson295189b2012-06-20 16:38:30 -070010479 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010480 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010481 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010482
Jeff Johnson295189b2012-06-20 16:38:30 -070010483 if ( 0 != status )
10484 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010485 hddLog(VOS_TRACE_LEVEL_ERROR,
10486 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010487 status);
10488 return -EINVAL;
10489 }
10490 }
10491 }
10492
10493 /* In SoftAp mode setting key direction for default mode */
10494 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
10495 {
10496 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
10497 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
10498 (eCSR_ENCRYPT_TYPE_AES !=
10499 pWextState->roamProfile.EncryptionType.encryptionType[0])
10500 )
10501 {
10502 /* Saving key direction for default key index to TX default */
10503 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
10504 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
10505 }
10506 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010507 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010508 return status;
10509}
10510
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010511#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10512static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
10513 struct net_device *ndev,
10514 u8 key_index,
10515 bool unicast, bool multicast)
10516#else
10517static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
10518 struct net_device *ndev,
10519 u8 key_index)
10520#endif
10521{
10522 int ret;
10523 vos_ssr_protect(__func__);
10524#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10525 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
10526 multicast);
10527#else
10528 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
10529#endif
10530 vos_ssr_unprotect(__func__);
10531
10532 return ret;
10533}
10534
Jeff Johnson295189b2012-06-20 16:38:30 -070010535/*
10536 * FUNCTION: wlan_hdd_cfg80211_inform_bss
10537 * This function is used to inform the BSS details to nl80211 interface.
10538 */
10539static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
10540 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
10541{
10542 struct net_device *dev = pAdapter->dev;
10543 struct wireless_dev *wdev = dev->ieee80211_ptr;
10544 struct wiphy *wiphy = wdev->wiphy;
10545 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
10546 int chan_no;
10547 int ie_length;
10548 const char *ie;
10549 unsigned int freq;
10550 struct ieee80211_channel *chan;
10551 int rssi = 0;
10552 struct cfg80211_bss *bss = NULL;
10553
Jeff Johnson295189b2012-06-20 16:38:30 -070010554 if( NULL == pBssDesc )
10555 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010556 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010557 return bss;
10558 }
10559
10560 chan_no = pBssDesc->channelId;
10561 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
10562 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
10563
10564 if( NULL == ie )
10565 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010566 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010567 return bss;
10568 }
10569
10570#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10571 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10572 {
10573 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10574 }
10575 else
10576 {
10577 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10578 }
10579#else
10580 freq = ieee80211_channel_to_frequency(chan_no);
10581#endif
10582
10583 chan = __ieee80211_get_channel(wiphy, freq);
10584
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053010585 if (!chan) {
10586 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
10587 return NULL;
10588 }
10589
Abhishek Singhaee43942014-06-16 18:55:47 +053010590 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070010591
Anand N Sunkad9f80b742015-07-30 20:05:51 +053010592 return cfg80211_inform_bss(wiphy, chan,
10593#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10594 CFG80211_BSS_FTYPE_UNKNOWN,
10595#endif
10596 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010597 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070010598 pBssDesc->capabilityInfo,
10599 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053010600 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070010601}
10602
10603
10604
10605/*
10606 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
10607 * This function is used to inform the BSS details to nl80211 interface.
10608 */
10609struct cfg80211_bss*
10610wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
10611 tSirBssDescription *bss_desc
10612 )
10613{
10614 /*
10615 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
10616 already exists in bss data base of cfg80211 for that particular BSS ID.
10617 Using cfg80211_inform_bss_frame to update the bss entry instead of
10618 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
10619 now there is no possibility to get the mgmt(probe response) frame from PE,
10620 converting bss_desc to ieee80211_mgmt(probe response) and passing to
10621 cfg80211_inform_bss_frame.
10622 */
10623 struct net_device *dev = pAdapter->dev;
10624 struct wireless_dev *wdev = dev->ieee80211_ptr;
10625 struct wiphy *wiphy = wdev->wiphy;
10626 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010627#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
10628 qcom_ie_age *qie_age = NULL;
10629 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
10630#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010631 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010632#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010633 const char *ie =
10634 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
10635 unsigned int freq;
10636 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053010637 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010638 struct cfg80211_bss *bss_status = NULL;
10639 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
10640 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070010641 hdd_context_t *pHddCtx;
10642 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070010643#ifdef WLAN_OPEN_SOURCE
10644 struct timespec ts;
10645#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010646
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010647
Wilson Yangf80a0542013-10-07 13:02:37 -070010648 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10649 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070010650 if (0 != status)
10651 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070010652 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010653 }
10654
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053010655 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070010656 if (!mgmt)
10657 {
10658 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10659 "%s: memory allocation failed ", __func__);
10660 return NULL;
10661 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070010662
Jeff Johnson295189b2012-06-20 16:38:30 -070010663 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070010664
10665#ifdef WLAN_OPEN_SOURCE
10666 /* Android does not want the timestamp from the frame.
10667 Instead it wants a monotonic increasing value */
10668 get_monotonic_boottime(&ts);
10669 mgmt->u.probe_resp.timestamp =
10670 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
10671#else
10672 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070010673 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
10674 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070010675
10676#endif
10677
Jeff Johnson295189b2012-06-20 16:38:30 -070010678 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
10679 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010680
10681#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
10682 /* GPS Requirement: need age ie per entry. Using vendor specific. */
10683 /* Assuming this is the last IE, copy at the end */
10684 ie_length -=sizeof(qcom_ie_age);
10685 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
10686 qie_age->element_id = QCOM_VENDOR_IE_ID;
10687 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
10688 qie_age->oui_1 = QCOM_OUI1;
10689 qie_age->oui_2 = QCOM_OUI2;
10690 qie_age->oui_3 = QCOM_OUI3;
10691 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
10692 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
10693#endif
10694
Jeff Johnson295189b2012-06-20 16:38:30 -070010695 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053010696 if (bss_desc->fProbeRsp)
10697 {
10698 mgmt->frame_control |=
10699 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
10700 }
10701 else
10702 {
10703 mgmt->frame_control |=
10704 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
10705 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010706
10707#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010708 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010709 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
10710 {
10711 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10712 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010713 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010714 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
10715
10716 {
10717 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10718 }
10719 else
10720 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010721 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
10722 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070010723 kfree(mgmt);
10724 return NULL;
10725 }
10726#else
10727 freq = ieee80211_channel_to_frequency(chan_no);
10728#endif
10729 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010730 /*when the band is changed on the fly using the GUI, three things are done
10731 * 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)
10732 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
10733 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
10734 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
10735 * and discards the channels correponding to previous band and calls back with zero bss results.
10736 * 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
10737 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
10738 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
10739 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
10740 * So drop the bss and continue to next bss.
10741 */
10742 if(chan == NULL)
10743 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010744 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070010745 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010746 return NULL;
10747 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053010748 /*To keep the rssi icon of the connected AP in the scan window
10749 *and the rssi icon of the wireless networks in sync
10750 * */
10751 if (( eConnectionState_Associated ==
10752 pAdapter->sessionCtx.station.conn_info.connState ) &&
10753 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
10754 pAdapter->sessionCtx.station.conn_info.bssId,
10755 WNI_CFG_BSSID_LEN)) &&
10756 (pHddCtx->hdd_wlan_suspended == FALSE))
10757 {
10758 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
10759 rssi = (pAdapter->rssi * 100);
10760 }
10761 else
10762 {
10763 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
10764 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010765
Nirav Shah20ac06f2013-12-12 18:14:06 +053010766 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053010767 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
10768 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053010769
Jeff Johnson295189b2012-06-20 16:38:30 -070010770 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
10771 frame_len, rssi, GFP_KERNEL);
10772 kfree(mgmt);
10773 return bss_status;
10774}
10775
10776/*
10777 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
10778 * This function is used to update the BSS data base of CFG8011
10779 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010780struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010781 tCsrRoamInfo *pRoamInfo
10782 )
10783{
10784 tCsrRoamConnectedProfile roamProfile;
10785 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10786 struct cfg80211_bss *bss = NULL;
10787
10788 ENTER();
10789
10790 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
10791 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
10792
10793 if (NULL != roamProfile.pBssDesc)
10794 {
Girish Gowlif4b68022014-08-28 23:18:57 +053010795 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10796 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070010797
10798 if (NULL == bss)
10799 {
10800 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
10801 __func__);
10802 }
10803
10804 sme_RoamFreeConnectProfile(hHal, &roamProfile);
10805 }
10806 else
10807 {
10808 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
10809 __func__);
10810 }
10811 return bss;
10812}
10813
10814/*
10815 * FUNCTION: wlan_hdd_cfg80211_update_bss
10816 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010817static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
10818 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070010819 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010820{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010821 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010822 tCsrScanResultInfo *pScanResult;
10823 eHalStatus status = 0;
10824 tScanResultHandle pResult;
10825 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010826 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010827 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070010828 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010829
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010830 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10831 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
10832 NO_SESSION, pAdapter->sessionId));
10833
Wilson Yangf80a0542013-10-07 13:02:37 -070010834 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10835
10836 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070010837 {
Wilson Yangf80a0542013-10-07 13:02:37 -070010838 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10839 "%s:LOGP in Progress. Ignore!!!",__func__);
10840 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010841 }
10842
Wilson Yangf80a0542013-10-07 13:02:37 -070010843
10844 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053010845 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070010846 {
10847 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10848 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
10849 return VOS_STATUS_E_PERM;
10850 }
10851
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010852 if (pAdapter->request != NULL)
10853 {
10854 if ((pAdapter->request->n_ssids == 1)
10855 && (pAdapter->request->ssids != NULL)
10856 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
10857 is_p2p_scan = true;
10858 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010859 /*
10860 * start getting scan results and populate cgf80211 BSS database
10861 */
10862 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
10863
10864 /* no scan results */
10865 if (NULL == pResult)
10866 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010867 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
10868 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053010869 wlan_hdd_get_frame_logs(pAdapter,
10870 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070010871 return status;
10872 }
10873
10874 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
10875
10876 while (pScanResult)
10877 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010878 /*
10879 * cfg80211_inform_bss() is not updating ie field of bss entry, if
10880 * entry already exists in bss data base of cfg80211 for that
10881 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
10882 * bss entry instead of cfg80211_inform_bss, But this call expects
10883 * mgmt packet as input. As of now there is no possibility to get
10884 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070010885 * ieee80211_mgmt(probe response) and passing to c
10886 * fg80211_inform_bss_frame.
10887 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010888 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
10889 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
10890 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010891 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10892 continue; //Skip the non p2p bss entries
10893 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010894 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10895 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010896
Jeff Johnson295189b2012-06-20 16:38:30 -070010897
10898 if (NULL == bss_status)
10899 {
10900 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010901 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010902 }
10903 else
10904 {
Yue Maf49ba872013-08-19 12:04:25 -070010905 cfg80211_put_bss(
10906#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
10907 wiphy,
10908#endif
10909 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010910 }
10911
10912 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10913 }
10914
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010915 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010916 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010917 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010918}
10919
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010920void
10921hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
10922{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010923 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080010924 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010925} /****** end hddPrintMacAddr() ******/
10926
10927void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010928hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010929{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010930 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010931 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010932 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
10933 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
10934 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010935} /****** end hddPrintPmkId() ******/
10936
10937//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
10938//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
10939
10940//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
10941//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
10942
10943#define dump_bssid(bssid) \
10944 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010945 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
10946 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010947 }
10948
10949#define dump_pmkid(pMac, pmkid) \
10950 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010951 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
10952 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010953 }
10954
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070010955#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010956/*
10957 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
10958 * This function is used to notify the supplicant of a new PMKSA candidate.
10959 */
10960int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010961 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010962 int index, bool preauth )
10963{
Jeff Johnsone7245742012-09-05 17:12:55 -070010964#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010965 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010966 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010967
10968 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070010969 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010970
10971 if( NULL == pRoamInfo )
10972 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010973 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010974 return -EINVAL;
10975 }
10976
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010977 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
10978 {
10979 dump_bssid(pRoamInfo->bssid);
10980 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010981 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010982 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010983#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010984 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010985}
10986#endif //FEATURE_WLAN_LFR
10987
Yue Maef608272013-04-08 23:09:17 -070010988#ifdef FEATURE_WLAN_LFR_METRICS
10989/*
10990 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
10991 * 802.11r/LFR metrics reporting function to report preauth initiation
10992 *
10993 */
10994#define MAX_LFR_METRICS_EVENT_LENGTH 100
10995VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
10996 tCsrRoamInfo *pRoamInfo)
10997{
10998 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10999 union iwreq_data wrqu;
11000
11001 ENTER();
11002
11003 if (NULL == pAdapter)
11004 {
11005 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
11006 return VOS_STATUS_E_FAILURE;
11007 }
11008
11009 /* create the event */
11010 memset(&wrqu, 0, sizeof(wrqu));
11011 memset(metrics_notification, 0, sizeof(metrics_notification));
11012
11013 wrqu.data.pointer = metrics_notification;
11014 wrqu.data.length = scnprintf(metrics_notification,
11015 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
11016 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
11017
11018 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
11019
11020 EXIT();
11021
11022 return VOS_STATUS_SUCCESS;
11023}
11024
11025/*
11026 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
11027 * 802.11r/LFR metrics reporting function to report preauth completion
11028 * or failure
11029 */
11030VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
11031 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
11032{
11033 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
11034 union iwreq_data wrqu;
11035
11036 ENTER();
11037
11038 if (NULL == pAdapter)
11039 {
11040 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
11041 return VOS_STATUS_E_FAILURE;
11042 }
11043
11044 /* create the event */
11045 memset(&wrqu, 0, sizeof(wrqu));
11046 memset(metrics_notification, 0, sizeof(metrics_notification));
11047
11048 scnprintf(metrics_notification, sizeof(metrics_notification),
11049 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
11050 MAC_ADDR_ARRAY(pRoamInfo->bssid));
11051
11052 if (1 == preauth_status)
11053 strncat(metrics_notification, " TRUE", 5);
11054 else
11055 strncat(metrics_notification, " FALSE", 6);
11056
11057 wrqu.data.pointer = metrics_notification;
11058 wrqu.data.length = strlen(metrics_notification);
11059
11060 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
11061
11062 EXIT();
11063
11064 return VOS_STATUS_SUCCESS;
11065}
11066
11067/*
11068 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
11069 * 802.11r/LFR metrics reporting function to report handover initiation
11070 *
11071 */
11072VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
11073 tCsrRoamInfo *pRoamInfo)
11074{
11075 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
11076 union iwreq_data wrqu;
11077
11078 ENTER();
11079
11080 if (NULL == pAdapter)
11081 {
11082 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
11083 return VOS_STATUS_E_FAILURE;
11084 }
11085
11086 /* create the event */
11087 memset(&wrqu, 0, sizeof(wrqu));
11088 memset(metrics_notification, 0, sizeof(metrics_notification));
11089
11090 wrqu.data.pointer = metrics_notification;
11091 wrqu.data.length = scnprintf(metrics_notification,
11092 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
11093 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
11094
11095 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
11096
11097 EXIT();
11098
11099 return VOS_STATUS_SUCCESS;
11100}
11101#endif
11102
Jeff Johnson295189b2012-06-20 16:38:30 -070011103/*
11104 * FUNCTION: hdd_cfg80211_scan_done_callback
11105 * scanning callback function, called after finishing scan
11106 *
11107 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011108static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070011109 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
11110{
11111 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011112 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070011113 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011114 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070011115 struct cfg80211_scan_request *req = NULL;
11116 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011117 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011118 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011119 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011120 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011121
11122 ENTER();
11123
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011124 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053011125 if (NULL == pHddCtx) {
11126 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053011127 goto allow_suspend;
11128 }
11129
11130 pScanInfo = &pHddCtx->scan_info;
11131
Jeff Johnson295189b2012-06-20 16:38:30 -070011132 hddLog(VOS_TRACE_LEVEL_INFO,
11133 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080011134 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011135 __func__, halHandle, pContext, (int) scanId, (int) status);
11136
Kiet Lamac06e2c2013-10-23 16:25:07 +053011137 pScanInfo->mScanPendingCounter = 0;
11138
Jeff Johnson295189b2012-06-20 16:38:30 -070011139 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011140 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070011141 &pScanInfo->scan_req_completion_event,
11142 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011143 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070011144 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053011145 hddLog(VOS_TRACE_LEVEL_ERROR,
11146 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070011147 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011148 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070011149 }
11150
Yue Maef608272013-04-08 23:09:17 -070011151 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070011152 {
11153 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070011154 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070011155 }
11156
11157 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011158 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070011159 {
11160 hddLog(VOS_TRACE_LEVEL_INFO,
11161 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080011162 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070011163 (int) scanId);
11164 }
11165
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011166 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070011167 pAdapter);
11168
11169 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011170 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011171
11172
11173 /* If any client wait scan result through WEXT
11174 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011175 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070011176 {
11177 /* The other scan request waiting for current scan finish
11178 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011179 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070011180 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011181 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070011182 }
11183 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011184 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070011185 {
11186 struct net_device *dev = pAdapter->dev;
11187 union iwreq_data wrqu;
11188 int we_event;
11189 char *msg;
11190
11191 memset(&wrqu, '\0', sizeof(wrqu));
11192 we_event = SIOCGIWSCAN;
11193 msg = NULL;
11194 wireless_send_event(dev, we_event, &wrqu, msg);
11195 }
11196 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011197 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011198
11199 /* Get the Scan Req */
11200 req = pAdapter->request;
11201
11202 if (!req)
11203 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011204 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011205 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070011206 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070011207 }
11208
Jeff Johnson295189b2012-06-20 16:38:30 -070011209 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011210 /* Scan is no longer pending */
11211 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011212
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011213 /* last_scan_timestamp is used to decide if new scan
11214 * is needed or not on station interface. If last station
11215 * scan time and new station scan time is less then
11216 * last_scan_timestamp ; driver will return cached scan.
11217 */
11218 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
11219 {
11220 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
11221
11222 if ( req->n_channels )
11223 {
11224 for (i = 0; i < req->n_channels ; i++ )
11225 {
11226 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
11227 }
11228 /* store no of channel scanned */
11229 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
11230 }
11231
11232 }
11233
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070011234 /*
11235 * cfg80211_scan_done informing NL80211 about completion
11236 * of scanning
11237 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011238 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
11239 {
11240 aborted = true;
11241 }
11242 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080011243 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070011244
Siddharth Bhal76972212014-10-15 16:22:51 +053011245 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
11246 /* Generate new random mac addr for next scan */
11247 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
11248 hdd_processSpoofMacAddrRequest(pHddCtx);
11249 }
11250
Jeff Johnsone7245742012-09-05 17:12:55 -070011251allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011252 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011253 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011254
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070011255 /* Acquire wakelock to handle the case where APP's tries to suspend
11256 * immediatly after the driver gets connect request(i.e after scan)
11257 * from supplicant, this result in app's is suspending and not able
11258 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011259 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070011260
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070011261#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011262 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070011263#endif
11264
Jeff Johnson295189b2012-06-20 16:38:30 -070011265 EXIT();
11266 return 0;
11267}
11268
11269/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053011270 * FUNCTION: hdd_isConnectionInProgress
11271 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011272 *
11273 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011274v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011275{
11276 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11277 hdd_station_ctx_t *pHddStaCtx = NULL;
11278 hdd_adapter_t *pAdapter = NULL;
11279 VOS_STATUS status = 0;
11280 v_U8_t staId = 0;
11281 v_U8_t *staMac = NULL;
11282
c_hpothu9b781ba2013-12-30 20:57:45 +053011283 if (TRUE == pHddCtx->btCoexModeSet)
11284 {
11285 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053011286 FL("BTCoex Mode operation in progress"));
11287 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053011288 }
11289
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011290 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11291
11292 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11293 {
11294 pAdapter = pAdapterNode->pAdapter;
11295
11296 if( pAdapter )
11297 {
11298 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011299 "%s: Adapter with device mode %s (%d) exists",
11300 __func__, hdd_device_modetoString(pAdapter->device_mode),
11301 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011302 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053011303 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11304 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
11305 (eConnectionState_Connecting ==
11306 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
11307 {
11308 hddLog(VOS_TRACE_LEVEL_ERROR,
11309 "%s: %p(%d) Connection is in progress", __func__,
11310 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
11311 return VOS_TRUE;
11312 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011313 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053011314 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011315 {
11316 hddLog(VOS_TRACE_LEVEL_ERROR,
11317 "%s: %p(%d) Reassociation is in progress", __func__,
11318 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
11319 return VOS_TRUE;
11320 }
11321 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011322 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11323 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011324 {
11325 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11326 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011327 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011328 {
11329 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
11330 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080011331 "%s: client " MAC_ADDRESS_STR
11332 " is in the middle of WPS/EAPOL exchange.", __func__,
11333 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053011334 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011335 }
11336 }
11337 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
11338 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
11339 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011340 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11341 ptSapContext pSapCtx = NULL;
11342 pSapCtx = VOS_GET_SAP_CB(pVosContext);
11343 if(pSapCtx == NULL){
11344 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11345 FL("psapCtx is NULL"));
11346 return VOS_FALSE;
11347 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011348 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
11349 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011350 if ((pSapCtx->aStaInfo[staId].isUsed) &&
11351 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011352 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011353 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011354
11355 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080011356 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
11357 "middle of WPS/EAPOL exchange.", __func__,
11358 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053011359 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011360 }
11361 }
11362 }
11363 }
11364 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11365 pAdapterNode = pNext;
11366 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053011367 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011368}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011369
11370/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011371 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070011372 * this scan respond to scan trigger and update cfg80211 scan database
11373 * later, scan dump command can be used to recieve scan results
11374 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011375int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080011376#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11377 struct net_device *dev,
11378#endif
11379 struct cfg80211_scan_request *request)
11380{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011381 hdd_adapter_t *pAdapter = NULL;
11382 hdd_context_t *pHddCtx = NULL;
11383 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011384 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011385 tCsrScanRequest scanRequest;
11386 tANI_U8 *channelList = NULL, i;
11387 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011388 int status;
11389 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011390 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011391 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053011392 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011393 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053011394 v_S7_t rssi=0;
11395 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011396
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011397#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
11398 struct net_device *dev = NULL;
11399 if (NULL == request)
11400 {
11401 hddLog(VOS_TRACE_LEVEL_ERROR,
11402 "%s: scan req param null", __func__);
11403 return -EINVAL;
11404 }
11405 dev = request->wdev->netdev;
11406#endif
11407
11408 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11409 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
11410 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11411
Jeff Johnson295189b2012-06-20 16:38:30 -070011412 ENTER();
11413
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011414 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11415 __func__, hdd_device_modetoString(pAdapter->device_mode),
11416 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011417
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011418 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011419 if (0 != status)
11420 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011421 return status;
11422 }
11423
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011424 if (NULL == pwextBuf)
11425 {
11426 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
11427 __func__);
11428 return -EIO;
11429 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011430 cfg_param = pHddCtx->cfg_ini;
11431 pScanInfo = &pHddCtx->scan_info;
11432
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053011433 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11434 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
11435 {
11436 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
11437 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
11438 }
11439
Jeff Johnson295189b2012-06-20 16:38:30 -070011440#ifdef WLAN_BTAMP_FEATURE
11441 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011442 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070011443 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011444 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011445 "%s: No scanning when AMP is on", __func__);
11446 return -EOPNOTSUPP;
11447 }
11448#endif
11449 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011450 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011451 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011452 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011453 "%s: Not scanning on device_mode = %s (%d)",
11454 __func__, hdd_device_modetoString(pAdapter->device_mode),
11455 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011456 return -EOPNOTSUPP;
11457 }
11458
11459 if (TRUE == pScanInfo->mScanPending)
11460 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053011461 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
11462 {
11463 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
11464 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011465 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070011466 }
11467
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053011468 // Don't allow scan if PNO scan is going on.
11469 if (pHddCtx->isPnoEnable)
11470 {
11471 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11472 FL("pno scan in progress"));
11473 return -EBUSY;
11474 }
11475
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011476 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070011477 //Channel and action frame is pending
11478 //Otherwise Cancel Remain On Channel and allow Scan
11479 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011480 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070011481 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053011482 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070011483 return -EBUSY;
11484 }
11485
Jeff Johnson295189b2012-06-20 16:38:30 -070011486 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
11487 {
11488 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080011489 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011490 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011491 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011492 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
11493 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011494 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011495 "%s: MAX TM Level Scan not allowed", __func__);
11496 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011497 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070011498 }
11499 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
11500
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011501 /* Check if scan is allowed at this point of time.
11502 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011503 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011504 {
11505 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
11506 return -EBUSY;
11507 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011508
Jeff Johnson295189b2012-06-20 16:38:30 -070011509 vos_mem_zero( &scanRequest, sizeof(scanRequest));
11510
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011511 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
11512 * Becasue of this, driver is assuming that this is not wildcard scan and so
11513 * is not aging out the scan results.
11514 */
11515 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011516 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011517 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011518 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011519
11520 if ((request->ssids) && (0 < request->n_ssids))
11521 {
11522 tCsrSSIDInfo *SsidInfo;
11523 int j;
11524 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
11525 /* Allocate num_ssid tCsrSSIDInfo structure */
11526 SsidInfo = scanRequest.SSIDs.SSIDList =
11527 ( tCsrSSIDInfo *)vos_mem_malloc(
11528 request->n_ssids*sizeof(tCsrSSIDInfo));
11529
11530 if(NULL == scanRequest.SSIDs.SSIDList)
11531 {
11532 hddLog(VOS_TRACE_LEVEL_ERROR,
11533 "%s: memory alloc failed SSIDInfo buffer", __func__);
11534 return -ENOMEM;
11535 }
11536
11537 /* copy all the ssid's and their length */
11538 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
11539 {
11540 /* get the ssid length */
11541 SsidInfo->SSID.length = request->ssids[j].ssid_len;
11542 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
11543 SsidInfo->SSID.length);
11544 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
11545 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
11546 j, SsidInfo->SSID.ssId);
11547 }
11548 /* set the scan type to active */
11549 scanRequest.scanType = eSIR_ACTIVE_SCAN;
11550 }
11551 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011552 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011553 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11554 TRACE_CODE_HDD_CFG80211_SCAN,
11555 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070011556 /* set the scan type to active */
11557 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070011558 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011559 else
11560 {
11561 /*Set the scan type to default type, in this case it is ACTIVE*/
11562 scanRequest.scanType = pScanInfo->scan_mode;
11563 }
11564 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
11565 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070011566
11567 /* set BSSType to default type */
11568 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
11569
11570 /*TODO: scan the requested channels only*/
11571
11572 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011573 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070011574 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011575 hddLog(VOS_TRACE_LEVEL_WARN,
11576 "No of Scan Channels exceeded limit: %d", request->n_channels);
11577 request->n_channels = MAX_CHANNEL;
11578 }
11579
11580 hddLog(VOS_TRACE_LEVEL_INFO,
11581 "No of Scan Channels: %d", request->n_channels);
11582
11583
11584 if( request->n_channels )
11585 {
11586 char chList [(request->n_channels*5)+1];
11587 int len;
11588 channelList = vos_mem_malloc( request->n_channels );
11589 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053011590 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011591 hddLog(VOS_TRACE_LEVEL_ERROR,
11592 "%s: memory alloc failed channelList", __func__);
11593 status = -ENOMEM;
11594 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053011595 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011596
11597 for( i = 0, len = 0; i < request->n_channels ; i++ )
11598 {
11599 channelList[i] = request->channels[i]->hw_value;
11600 len += snprintf(chList+len, 5, "%d ", channelList[i]);
11601 }
11602
Nirav Shah20ac06f2013-12-12 18:14:06 +053011603 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011604 "Channel-List: %s ", chList);
11605 }
c_hpothu53512302014-04-15 18:49:53 +053011606
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011607 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
11608 scanRequest.ChannelInfo.ChannelList = channelList;
11609
11610 /* set requestType to full scan */
11611 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
11612
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011613 /* if there is back to back scan happening in driver with in
11614 * nDeferScanTimeInterval interval driver should defer new scan request
11615 * and should provide last cached scan results instead of new channel list.
11616 * This rule is not applicable if scan is p2p scan.
11617 * This condition will work only in case when last request no of channels
11618 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053011619 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053011620 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011621 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011622
Sushant Kaushik86592172015-04-27 16:35:03 +053011623 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
11624 /* if wps ie is NULL , then only defer scan */
11625 if ( pWpsIe == NULL &&
11626 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053011627 {
11628 if ( pScanInfo->last_scan_timestamp !=0 &&
11629 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
11630 {
11631 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
11632 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
11633 vos_mem_compare(pScanInfo->last_scan_channelList,
11634 channelList, pScanInfo->last_scan_numChannels))
11635 {
11636 hddLog(VOS_TRACE_LEVEL_WARN,
11637 " New and old station scan time differ is less then %u",
11638 pHddCtx->cfg_ini->nDeferScanTimeInterval);
11639
11640 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011641 pAdapter);
11642
Agarwal Ashish57e84372014-12-05 18:26:53 +053011643 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053011644 "Return old cached scan as all channels and no of channels are same");
11645
Agarwal Ashish57e84372014-12-05 18:26:53 +053011646 if (0 > ret)
11647 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011648
Agarwal Ashish57e84372014-12-05 18:26:53 +053011649 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053011650
11651 status = eHAL_STATUS_SUCCESS;
11652 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053011653 }
11654 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011655 }
11656
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011657 /* Flush the scan results(only p2p beacons) for STA scan and P2P
11658 * search (Flush on both full scan and social scan but not on single
11659 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
11660 */
11661
11662 /* Supplicant does single channel scan after 8-way handshake
11663 * and in that case driver shoudnt flush scan results. If
11664 * driver flushes the scan results here and unfortunately if
11665 * the AP doesnt respond to our probe req then association
11666 * fails which is not desired
11667 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011668 if ((request->n_ssids == 1)
11669 && (request->ssids != NULL)
11670 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
11671 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011672
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011673 if( is_p2p_scan ||
11674 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011675 {
11676 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
11677 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
11678 pAdapter->sessionId );
11679 }
11680
11681 if( request->ie_len )
11682 {
11683 /* save this for future association (join requires this) */
11684 /*TODO: Array needs to be converted to dynamic allocation,
11685 * as multiple ie.s can be sent in cfg80211_scan_request structure
11686 * CR 597966
11687 */
11688 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
11689 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
11690 pScanInfo->scanAddIE.length = request->ie_len;
11691
11692 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11693 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11694 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011695 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011696 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070011697 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011698 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
11699 memcpy( pwextBuf->roamProfile.addIEScan,
11700 request->ie, request->ie_len);
11701 }
11702 else
11703 {
11704 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
11705 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011706 }
11707
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011708 }
11709 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
11710 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
11711
11712 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
11713 request->ie_len);
11714 if (pP2pIe != NULL)
11715 {
11716#ifdef WLAN_FEATURE_P2P_DEBUG
11717 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
11718 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
11719 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053011720 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011721 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
11722 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11723 "Go nego completed to Connection is started");
11724 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11725 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053011726 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011727 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
11728 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011729 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011730 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
11731 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11732 "Disconnected state to Connection is started");
11733 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11734 "for 4way Handshake");
11735 }
11736#endif
11737
11738 /* no_cck will be set during p2p find to disable 11b rates */
11739 if(TRUE == request->no_cck)
11740 {
11741 hddLog(VOS_TRACE_LEVEL_INFO,
11742 "%s: This is a P2P Search", __func__);
11743 scanRequest.p2pSearch = 1;
11744
11745 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053011746 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011747 /* set requestType to P2P Discovery */
11748 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
11749 }
11750
11751 /*
11752 Skip Dfs Channel in case of P2P Search
11753 if it is set in ini file
11754 */
11755 if(cfg_param->skipDfsChnlInP2pSearch)
11756 {
11757 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011758 }
11759 else
11760 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011761 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011762 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011763
Agarwal Ashish4f616132013-12-30 23:32:50 +053011764 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011765 }
11766 }
11767
11768 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
11769
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011770#ifdef FEATURE_WLAN_TDLS
11771 /* if tdls disagree scan right now, return immediately.
11772 tdls will schedule the scan when scan is allowed. (return SUCCESS)
11773 or will reject the scan if any TDLS is in progress. (return -EBUSY)
11774 */
11775 status = wlan_hdd_tdls_scan_callback (pAdapter,
11776 wiphy,
11777#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11778 dev,
11779#endif
11780 request);
11781 if(status <= 0)
11782 {
11783 if(!status)
11784 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
11785 "scan rejected %d", __func__, status);
11786 else
11787 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
11788 __func__, status);
11789
11790 return status;
11791 }
11792#endif
11793
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011794 /* acquire the wakelock to avoid the apps suspend during the scan. To
11795 * address the following issues.
11796 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
11797 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
11798 * for long time, this result in apps running at full power for long time.
11799 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
11800 * be stuck in full power because of resume BMPS
11801 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011802 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011803
Nirav Shah20ac06f2013-12-12 18:14:06 +053011804 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11805 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011806 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
11807 scanRequest.requestType, scanRequest.scanType,
11808 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053011809 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
11810
Siddharth Bhal76972212014-10-15 16:22:51 +053011811 if (pHddCtx->spoofMacAddr.isEnabled)
11812 {
11813 hddLog(VOS_TRACE_LEVEL_INFO,
11814 "%s: MAC Spoofing enabled for current scan", __func__);
11815 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
11816 * to fill TxBds for probe request during current scan
11817 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011818 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053011819 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011820
11821 if(status != VOS_STATUS_SUCCESS)
11822 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011823 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011824 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053011825#ifdef FEATURE_WLAN_TDLS
11826 wlan_hdd_tdls_scan_done_callback(pAdapter);
11827#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011828 goto free_mem;
11829 }
Siddharth Bhal76972212014-10-15 16:22:51 +053011830 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053011831 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070011832 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011833 pAdapter->sessionId, &scanRequest, &scanId,
11834 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070011835
Jeff Johnson295189b2012-06-20 16:38:30 -070011836 if (eHAL_STATUS_SUCCESS != status)
11837 {
11838 hddLog(VOS_TRACE_LEVEL_ERROR,
11839 "%s: sme_ScanRequest returned error %d", __func__, status);
11840 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011841 if(eHAL_STATUS_RESOURCES == status)
11842 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011843 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
11844 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011845 status = -EBUSY;
11846 } else {
11847 status = -EIO;
11848 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011849 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011850
11851#ifdef FEATURE_WLAN_TDLS
11852 wlan_hdd_tdls_scan_done_callback(pAdapter);
11853#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011854 goto free_mem;
11855 }
11856
11857 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011858 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011859 pAdapter->request = request;
11860 pScanInfo->scanId = scanId;
11861
11862 complete(&pScanInfo->scan_req_completion_event);
11863
11864free_mem:
11865 if( scanRequest.SSIDs.SSIDList )
11866 {
11867 vos_mem_free(scanRequest.SSIDs.SSIDList);
11868 }
11869
11870 if( channelList )
11871 vos_mem_free( channelList );
11872
11873 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011874 return status;
11875}
11876
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011877int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
11878#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11879 struct net_device *dev,
11880#endif
11881 struct cfg80211_scan_request *request)
11882{
11883 int ret;
11884
11885 vos_ssr_protect(__func__);
11886 ret = __wlan_hdd_cfg80211_scan(wiphy,
11887#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11888 dev,
11889#endif
11890 request);
11891 vos_ssr_unprotect(__func__);
11892
11893 return ret;
11894}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011895
11896void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
11897{
11898 v_U8_t iniDot11Mode =
11899 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
11900 eHddDot11Mode hddDot11Mode = iniDot11Mode;
11901
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011902 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
11903 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011904 switch ( iniDot11Mode )
11905 {
11906 case eHDD_DOT11_MODE_AUTO:
11907 case eHDD_DOT11_MODE_11ac:
11908 case eHDD_DOT11_MODE_11ac_ONLY:
11909#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053011910 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
11911 sme_IsFeatureSupportedByFW(DOT11AC) )
11912 hddDot11Mode = eHDD_DOT11_MODE_11ac;
11913 else
11914 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011915#else
11916 hddDot11Mode = eHDD_DOT11_MODE_11n;
11917#endif
11918 break;
11919 case eHDD_DOT11_MODE_11n:
11920 case eHDD_DOT11_MODE_11n_ONLY:
11921 hddDot11Mode = eHDD_DOT11_MODE_11n;
11922 break;
11923 default:
11924 hddDot11Mode = iniDot11Mode;
11925 break;
11926 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011927#ifdef WLAN_FEATURE_AP_HT40_24G
11928 if (operationChannel > SIR_11B_CHANNEL_END)
11929#endif
11930 {
11931 /* This call decides required channel bonding mode */
11932 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011933 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
11934 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011935 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011936}
11937
Jeff Johnson295189b2012-06-20 16:38:30 -070011938/*
11939 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011940 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011941 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011942int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011943 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070011944{
11945 int status = 0;
11946 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080011947 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011948 v_U32_t roamId;
11949 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070011950 eCsrAuthType RSNAuthType;
11951
11952 ENTER();
11953
11954 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080011955 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11956
11957 status = wlan_hdd_validate_context(pHddCtx);
11958 if (status)
11959 {
Yue Mae36e3552014-03-05 17:06:20 -080011960 return status;
11961 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011962
Jeff Johnson295189b2012-06-20 16:38:30 -070011963 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
11964 {
11965 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
11966 return -EINVAL;
11967 }
11968
11969 pRoamProfile = &pWextState->roamProfile;
11970
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011971 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070011972 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011973 hdd_station_ctx_t *pHddStaCtx;
11974 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011975
Siddharth Bhalda0d1622015-04-24 15:47:49 +053011976 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
11977
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011978 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070011979 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
11980 {
11981 /*QoS not enabled in cfg file*/
11982 pRoamProfile->uapsd_mask = 0;
11983 }
11984 else
11985 {
11986 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011987 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070011988 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
11989 }
11990
11991 pRoamProfile->SSIDs.numOfSSIDs = 1;
11992 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
11993 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011994 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070011995 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
11996 ssid, ssid_len);
11997
11998 if (bssid)
11999 {
12000 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
12001 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
12002 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012003 /* Save BSSID in seperate variable as well, as RoamProfile
12004 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070012005 case of join failure we should send valid BSSID to supplicant
12006 */
12007 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
12008 WNI_CFG_BSSID_LEN);
12009 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070012010 else
12011 {
12012 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
12013 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012014
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012015 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
12016 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070012017 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
12018 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012019 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012020 /*set gen ie*/
12021 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
12022 /*set auth*/
12023 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
12024 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012025#ifdef FEATURE_WLAN_WAPI
12026 if (pAdapter->wapi_info.nWapiMode)
12027 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012028 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012029 switch (pAdapter->wapi_info.wapiAuthMode)
12030 {
12031 case WAPI_AUTH_MODE_PSK:
12032 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012033 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012034 pAdapter->wapi_info.wapiAuthMode);
12035 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
12036 break;
12037 }
12038 case WAPI_AUTH_MODE_CERT:
12039 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012040 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012041 pAdapter->wapi_info.wapiAuthMode);
12042 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
12043 break;
12044 }
12045 } // End of switch
12046 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
12047 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
12048 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012049 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012050 pRoamProfile->AuthType.numEntries = 1;
12051 pRoamProfile->EncryptionType.numEntries = 1;
12052 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
12053 pRoamProfile->mcEncryptionType.numEntries = 1;
12054 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
12055 }
12056 }
12057#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053012058#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053012059 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053012060 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
12061 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
12062 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053012063 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
12064 sizeof (tSirGtkOffloadParams));
12065 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053012066 }
12067#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012068 pRoamProfile->csrPersona = pAdapter->device_mode;
12069
Jeff Johnson32d95a32012-09-10 13:15:23 -070012070 if( operatingChannel )
12071 {
12072 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
12073 pRoamProfile->ChannelInfo.numOfChannels = 1;
12074 }
Chet Lanctot186b5732013-03-18 10:26:30 -070012075 else
12076 {
12077 pRoamProfile->ChannelInfo.ChannelList = NULL;
12078 pRoamProfile->ChannelInfo.numOfChannels = 0;
12079 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012080 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
12081 {
12082 hdd_select_cbmode(pAdapter,operatingChannel);
12083 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012084
Agarwal Ashish40f9b872015-09-01 16:17:35 +053012085 /*
12086 * Change conn_state to connecting before sme_RoamConnect(),
12087 * because sme_RoamConnect() has a direct path to call
12088 * hdd_smeRoamCallback(), which will change the conn_state
12089 * If direct path, conn_state will be accordingly changed
12090 * to NotConnected or Associated by either
12091 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
12092 * in sme_RoamCallback()
12093 * if sme_RomConnect is to be queued,
12094 * Connecting state will remain until it is completed.
12095 * If connection state is not changed,
12096 * connection state will remain in eConnectionState_NotConnected state.
12097 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
12098 * if conn state is eConnectionState_NotConnected.
12099 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
12100 * informed of connect result indication which is an issue.
12101 */
12102
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053012103 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
12104 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053012105 {
12106 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053012107 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080012108 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
12109 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053012110 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012111 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070012112 pAdapter->sessionId, pRoamProfile, &roamId);
12113
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053012114 if ((eHAL_STATUS_SUCCESS != status) &&
12115 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
12116 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053012117
12118 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053012119 hddLog(VOS_TRACE_LEVEL_ERROR,
12120 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
12121 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080012122 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053012123 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080012124 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053012125 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080012126
12127 pRoamProfile->ChannelInfo.ChannelList = NULL;
12128 pRoamProfile->ChannelInfo.numOfChannels = 0;
12129
Jeff Johnson295189b2012-06-20 16:38:30 -070012130 }
12131 else
12132 {
12133 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
12134 return -EINVAL;
12135 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080012136 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012137 return status;
12138}
12139
12140/*
12141 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
12142 * This function is used to set the authentication type (OPEN/SHARED).
12143 *
12144 */
12145static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
12146 enum nl80211_auth_type auth_type)
12147{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012148 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012149 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12150
12151 ENTER();
12152
12153 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012154 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070012155 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012156 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012157 hddLog(VOS_TRACE_LEVEL_INFO,
12158 "%s: set authentication type to AUTOSWITCH", __func__);
12159 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
12160 break;
12161
12162 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070012163#ifdef WLAN_FEATURE_VOWIFI_11R
12164 case NL80211_AUTHTYPE_FT:
12165#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012166 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070012167 "%s: set authentication type to OPEN", __func__);
12168 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
12169 break;
12170
12171 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012172 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070012173 "%s: set authentication type to SHARED", __func__);
12174 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
12175 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012176#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012177 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012178 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070012179 "%s: set authentication type to CCKM WPA", __func__);
12180 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
12181 break;
12182#endif
12183
12184
12185 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012186 hddLog(VOS_TRACE_LEVEL_ERROR,
12187 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012188 auth_type);
12189 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
12190 return -EINVAL;
12191 }
12192
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012193 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012194 pHddStaCtx->conn_info.authType;
12195 return 0;
12196}
12197
12198/*
12199 * FUNCTION: wlan_hdd_set_akm_suite
12200 * This function is used to set the key mgmt type(PSK/8021x).
12201 *
12202 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012203static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012204 u32 key_mgmt
12205 )
12206{
12207 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12208 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053012209 /* Should be in ieee802_11_defs.h */
12210#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
12211#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070012212 /*set key mgmt type*/
12213 switch(key_mgmt)
12214 {
12215 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053012216 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012217#ifdef WLAN_FEATURE_VOWIFI_11R
12218 case WLAN_AKM_SUITE_FT_PSK:
12219#endif
12220 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070012221 __func__);
12222 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
12223 break;
12224
12225 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053012226 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012227#ifdef WLAN_FEATURE_VOWIFI_11R
12228 case WLAN_AKM_SUITE_FT_8021X:
12229#endif
12230 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070012231 __func__);
12232 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
12233 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012234#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012235#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
12236#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
12237 case WLAN_AKM_SUITE_CCKM:
12238 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
12239 __func__);
12240 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
12241 break;
12242#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070012243#ifndef WLAN_AKM_SUITE_OSEN
12244#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
12245 case WLAN_AKM_SUITE_OSEN:
12246 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
12247 __func__);
12248 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
12249 break;
12250#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012251
12252 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012253 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012254 __func__, key_mgmt);
12255 return -EINVAL;
12256
12257 }
12258 return 0;
12259}
12260
12261/*
12262 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012263 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070012264 * (NONE/WEP40/WEP104/TKIP/CCMP).
12265 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012266static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
12267 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070012268 bool ucast
12269 )
12270{
12271 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012272 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012273 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12274
12275 ENTER();
12276
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012277 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012278 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012279 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070012280 __func__, cipher);
12281 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12282 }
12283 else
12284 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012285
Jeff Johnson295189b2012-06-20 16:38:30 -070012286 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012287 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012288 {
12289 case IW_AUTH_CIPHER_NONE:
12290 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12291 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012292
Jeff Johnson295189b2012-06-20 16:38:30 -070012293 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012294 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070012295 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012296
Jeff Johnson295189b2012-06-20 16:38:30 -070012297 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012298 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070012299 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012300
Jeff Johnson295189b2012-06-20 16:38:30 -070012301 case WLAN_CIPHER_SUITE_TKIP:
12302 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
12303 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012304
Jeff Johnson295189b2012-06-20 16:38:30 -070012305 case WLAN_CIPHER_SUITE_CCMP:
12306 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12307 break;
12308#ifdef FEATURE_WLAN_WAPI
12309 case WLAN_CIPHER_SUITE_SMS4:
12310 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
12311 break;
12312#endif
12313
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012314#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012315 case WLAN_CIPHER_SUITE_KRK:
12316 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
12317 break;
12318#endif
12319 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012320 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012321 __func__, cipher);
12322 return -EOPNOTSUPP;
12323 }
12324 }
12325
12326 if (ucast)
12327 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012328 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012329 __func__, encryptionType);
12330 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12331 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012332 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012333 encryptionType;
12334 }
12335 else
12336 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012337 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012338 __func__, encryptionType);
12339 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
12340 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
12341 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
12342 }
12343
12344 return 0;
12345}
12346
12347
12348/*
12349 * FUNCTION: wlan_hdd_cfg80211_set_ie
12350 * This function is used to parse WPA/RSN IE's.
12351 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012352int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012353#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12354 const u8 *ie,
12355#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012356 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012357#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012358 size_t ie_len
12359 )
12360{
12361 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012362#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12363 const u8 *genie = ie;
12364#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012365 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012366#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012367 v_U16_t remLen = ie_len;
12368#ifdef FEATURE_WLAN_WAPI
12369 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
12370 u16 *tmp;
12371 v_U16_t akmsuiteCount;
12372 int *akmlist;
12373#endif
12374 ENTER();
12375
12376 /* clear previous assocAddIE */
12377 pWextState->assocAddIE.length = 0;
12378 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012379 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012380
12381 while (remLen >= 2)
12382 {
12383 v_U16_t eLen = 0;
12384 v_U8_t elementId;
12385 elementId = *genie++;
12386 eLen = *genie++;
12387 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012388
Arif Hussain6d2a3322013-11-17 19:50:10 -080012389 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070012390 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012391
12392 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070012393 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012394 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012395 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 -070012396 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012397 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012398 "%s: Invalid WPA IE", __func__);
12399 return -EINVAL;
12400 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012401 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070012402 {
12403 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012404 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012405 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012406
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012407 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012408 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012409 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
12410 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012411 VOS_ASSERT(0);
12412 return -ENOMEM;
12413 }
12414 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
12415 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12416 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012417
Jeff Johnson295189b2012-06-20 16:38:30 -070012418 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
12419 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12420 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12421 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012422 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
12423 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012424 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
12425 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
12426 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
12427 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
12428 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
12429 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012430 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053012431 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070012432 {
12433 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012434 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012435 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012436
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012437 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012438 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012439 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12440 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012441 VOS_ASSERT(0);
12442 return -ENOMEM;
12443 }
12444 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
12445 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12446 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012447
Jeff Johnson295189b2012-06-20 16:38:30 -070012448 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12449 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12450 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012451#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012452 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
12453 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012454 /*Consider WFD IE, only for P2P Client */
12455 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
12456 {
12457 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012458 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012459 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012460
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012461 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012462 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012463 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12464 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012465 VOS_ASSERT(0);
12466 return -ENOMEM;
12467 }
12468 // WFD IE is saved to Additional IE ; it should be accumulated to handle
12469 // WPS IE + P2P IE + WFD IE
12470 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12471 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012472
Jeff Johnson295189b2012-06-20 16:38:30 -070012473 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12474 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12475 }
12476#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012477 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012478 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012479 HS20_OUI_TYPE_SIZE)) )
12480 {
12481 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012482 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012483 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012484
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012485 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012486 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012487 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12488 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012489 VOS_ASSERT(0);
12490 return -ENOMEM;
12491 }
12492 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12493 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012494
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012495 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12496 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12497 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012498 /* Appending OSEN Information Element in Assiciation Request */
12499 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
12500 OSEN_OUI_TYPE_SIZE)) )
12501 {
12502 v_U16_t curAddIELen = pWextState->assocAddIE.length;
12503 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
12504 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012505
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012506 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012507 {
12508 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12509 "Need bigger buffer space");
12510 VOS_ASSERT(0);
12511 return -ENOMEM;
12512 }
12513 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12514 pWextState->assocAddIE.length += eLen + 2;
12515
12516 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
12517 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12518 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12519 }
12520
Abhishek Singh4322e622015-06-10 15:42:54 +053012521 /* Update only for WPA IE */
12522 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
12523 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070012524
12525 /* populating as ADDIE in beacon frames */
12526 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012527 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070012528 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
12529 {
12530 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
12531 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
12532 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
12533 {
12534 hddLog(LOGE,
12535 "Coldn't pass "
12536 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
12537 }
12538 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
12539 else
12540 hddLog(LOGE,
12541 "Could not pass on "
12542 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
12543
12544 /* IBSS mode doesn't contain params->proberesp_ies still
12545 beaconIE's need to be populated in probe response frames */
12546 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
12547 {
12548 u16 rem_probe_resp_ie_len = eLen + 2;
12549 u8 probe_rsp_ie_len[3] = {0};
12550 u8 counter = 0;
12551
12552 /* Check Probe Resp Length if it is greater then 255 then
12553 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
12554 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
12555 not able Store More then 255 bytes into One Variable */
12556
12557 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
12558 {
12559 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
12560 {
12561 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
12562 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
12563 }
12564 else
12565 {
12566 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
12567 rem_probe_resp_ie_len = 0;
12568 }
12569 }
12570
12571 rem_probe_resp_ie_len = 0;
12572
12573 if (probe_rsp_ie_len[0] > 0)
12574 {
12575 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12576 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
12577 (tANI_U8*)(genie - 2),
12578 probe_rsp_ie_len[0], NULL,
12579 eANI_BOOLEAN_FALSE)
12580 == eHAL_STATUS_FAILURE)
12581 {
12582 hddLog(LOGE,
12583 "Could not pass"
12584 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
12585 }
12586 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
12587 }
12588
12589 if (probe_rsp_ie_len[1] > 0)
12590 {
12591 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12592 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
12593 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
12594 probe_rsp_ie_len[1], NULL,
12595 eANI_BOOLEAN_FALSE)
12596 == eHAL_STATUS_FAILURE)
12597 {
12598 hddLog(LOGE,
12599 "Could not pass"
12600 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
12601 }
12602 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
12603 }
12604
12605 if (probe_rsp_ie_len[2] > 0)
12606 {
12607 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12608 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
12609 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
12610 probe_rsp_ie_len[2], NULL,
12611 eANI_BOOLEAN_FALSE)
12612 == eHAL_STATUS_FAILURE)
12613 {
12614 hddLog(LOGE,
12615 "Could not pass"
12616 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
12617 }
12618 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
12619 }
12620
12621 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
12622 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
12623 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
12624 {
12625 hddLog(LOGE,
12626 "Could not pass"
12627 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
12628 }
12629 }
12630 else
12631 {
12632 // Reset WNI_CFG_PROBE_RSP Flags
12633 wlan_hdd_reset_prob_rspies(pAdapter);
12634
12635 hddLog(VOS_TRACE_LEVEL_INFO,
12636 "%s: No Probe Response IE received in set beacon",
12637 __func__);
12638 }
12639 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012640 break;
12641 case DOT11F_EID_RSN:
12642 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
12643 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
12644 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
12645 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
12646 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
12647 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053012648
12649 /* Appending Extended Capabilities with Interworking bit set
12650 * in Assoc Req.
12651 *
12652 * In assoc req this EXT Cap will only be taken into account if
12653 * interworkingService bit is set to 1. Currently
12654 * driver is only interested in interworkingService capability
12655 * from supplicant. If in future any other EXT Cap info is
12656 * required from supplicat, it needs to be handled while
12657 * sending Assoc Req in LIM.
12658 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012659 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012660 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012661 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012662 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012663 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012664
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012665 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012666 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012667 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12668 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012669 VOS_ASSERT(0);
12670 return -ENOMEM;
12671 }
12672 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12673 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012674
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012675 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12676 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12677 break;
12678 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012679#ifdef FEATURE_WLAN_WAPI
12680 case WLAN_EID_WAPI:
12681 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012682 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012683 pAdapter->wapi_info.nWapiMode);
12684 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012685 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070012686 akmsuiteCount = WPA_GET_LE16(tmp);
12687 tmp = tmp + 1;
12688 akmlist = (int *)(tmp);
12689 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
12690 {
12691 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
12692 }
12693 else
12694 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012695 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070012696 VOS_ASSERT(0);
12697 return -EINVAL;
12698 }
12699
12700 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
12701 {
12702 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012703 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012704 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012705 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012706 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012707 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012708 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012709 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012710 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
12711 }
12712 break;
12713#endif
12714 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012715 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012716 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012717 /* when Unknown IE is received we should break and continue
12718 * to the next IE in the buffer instead we were returning
12719 * so changing this to break */
12720 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070012721 }
12722 genie += eLen;
12723 remLen -= eLen;
12724 }
12725 EXIT();
12726 return 0;
12727}
12728
12729/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012730 * FUNCTION: hdd_isWPAIEPresent
12731 * Parse the received IE to find the WPA IE
12732 *
12733 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012734static bool hdd_isWPAIEPresent(
12735#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
12736 const u8 *ie,
12737#else
12738 u8 *ie,
12739#endif
12740 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012741{
12742 v_U8_t eLen = 0;
12743 v_U16_t remLen = ie_len;
12744 v_U8_t elementId = 0;
12745
12746 while (remLen >= 2)
12747 {
12748 elementId = *ie++;
12749 eLen = *ie++;
12750 remLen -= 2;
12751 if (eLen > remLen)
12752 {
12753 hddLog(VOS_TRACE_LEVEL_ERROR,
12754 "%s: IE length is wrong %d", __func__, eLen);
12755 return FALSE;
12756 }
12757 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
12758 {
12759 /* OUI - 0x00 0X50 0XF2
12760 WPA Information Element - 0x01
12761 WPA version - 0x01*/
12762 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
12763 return TRUE;
12764 }
12765 ie += eLen;
12766 remLen -= eLen;
12767 }
12768 return FALSE;
12769}
12770
12771/*
Jeff Johnson295189b2012-06-20 16:38:30 -070012772 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012773 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012774 * parameters during connect operation.
12775 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012776int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012777 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012778 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012779{
12780 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012781 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012782 ENTER();
12783
12784 /*set wpa version*/
12785 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
12786
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012787 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012788 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053012789 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012790 {
12791 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12792 }
12793 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
12794 {
12795 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12796 }
12797 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012798
12799 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012800 pWextState->wpaVersion);
12801
12802 /*set authentication type*/
12803 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
12804
12805 if (0 > status)
12806 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012807 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012808 "%s: failed to set authentication type ", __func__);
12809 return status;
12810 }
12811
12812 /*set key mgmt type*/
12813 if (req->crypto.n_akm_suites)
12814 {
12815 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
12816 if (0 > status)
12817 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012818 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070012819 __func__);
12820 return status;
12821 }
12822 }
12823
12824 /*set pairwise cipher type*/
12825 if (req->crypto.n_ciphers_pairwise)
12826 {
12827 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
12828 req->crypto.ciphers_pairwise[0], true);
12829 if (0 > status)
12830 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012831 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012832 "%s: failed to set unicast cipher type", __func__);
12833 return status;
12834 }
12835 }
12836 else
12837 {
12838 /*Reset previous cipher suite to none*/
12839 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
12840 if (0 > status)
12841 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012842 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012843 "%s: failed to set unicast cipher type", __func__);
12844 return status;
12845 }
12846 }
12847
12848 /*set group cipher type*/
12849 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
12850 false);
12851
12852 if (0 > status)
12853 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012854 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070012855 __func__);
12856 return status;
12857 }
12858
Chet Lanctot186b5732013-03-18 10:26:30 -070012859#ifdef WLAN_FEATURE_11W
12860 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
12861#endif
12862
Jeff Johnson295189b2012-06-20 16:38:30 -070012863 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
12864 if (req->ie_len)
12865 {
12866 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
12867 if ( 0 > status)
12868 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012869 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012870 __func__);
12871 return status;
12872 }
12873 }
12874
12875 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012876 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012877 {
12878 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
12879 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
12880 )
12881 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012882 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070012883 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
12884 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012885 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012886 __func__);
12887 return -EOPNOTSUPP;
12888 }
12889 else
12890 {
12891 u8 key_len = req->key_len;
12892 u8 key_idx = req->key_idx;
12893
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012894 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012895 && (CSR_MAX_NUM_KEY > key_idx)
12896 )
12897 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012898 hddLog(VOS_TRACE_LEVEL_INFO,
12899 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012900 __func__, key_idx, key_len);
12901 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012902 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012903 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012904 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012905 (u8)key_len;
12906 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
12907 }
12908 }
12909 }
12910 }
12911
12912 return status;
12913}
12914
12915/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012916 * FUNCTION: wlan_hdd_try_disconnect
12917 * This function is used to disconnect from previous
12918 * connection
12919 */
12920static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
12921{
12922 long ret = 0;
12923 hdd_station_ctx_t *pHddStaCtx;
12924 eMib_dot11DesiredBssType connectedBssType;
12925
12926 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12927
12928 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
12929
12930 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
12931 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
12932 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
12933 {
12934 /* Issue disconnect to CSR */
12935 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12936 if( eHAL_STATUS_SUCCESS ==
12937 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12938 pAdapter->sessionId,
12939 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12940 {
12941 ret = wait_for_completion_interruptible_timeout(
12942 &pAdapter->disconnect_comp_var,
12943 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12944 if (0 >= ret)
12945 {
12946 hddLog(LOGE, FL("Failed to receive disconnect event"));
12947 return -EALREADY;
12948 }
12949 }
12950 }
12951 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
12952 {
12953 ret = wait_for_completion_interruptible_timeout(
12954 &pAdapter->disconnect_comp_var,
12955 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12956 if (0 >= ret)
12957 {
12958 hddLog(LOGE, FL("Failed to receive disconnect event"));
12959 return -EALREADY;
12960 }
12961 }
12962
12963 return 0;
12964}
12965
12966/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053012967 * FUNCTION: __wlan_hdd_cfg80211_connect
12968 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070012969 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012970static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012971 struct net_device *ndev,
12972 struct cfg80211_connect_params *req
12973 )
12974{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012975 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012976 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012977 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053012978 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012979
12980 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012981
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012982 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12983 TRACE_CODE_HDD_CFG80211_CONNECT,
12984 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012985 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012986 "%s: device_mode = %s (%d)", __func__,
12987 hdd_device_modetoString(pAdapter->device_mode),
12988 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012989
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012990 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012991 if (!pHddCtx)
12992 {
12993 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12994 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053012995 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012996 }
12997
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012998 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012999 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013000 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013001 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013002 }
13003
Agarwal Ashish51325b52014-06-16 16:50:49 +053013004 if (vos_max_concurrent_connections_reached()) {
13005 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
13006 return -ECONNREFUSED;
13007 }
13008
Jeff Johnson295189b2012-06-20 16:38:30 -070013009#ifdef WLAN_BTAMP_FEATURE
13010 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013011 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070013012 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013013 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013014 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080013015 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070013016 }
13017#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053013018
13019 //If Device Mode is Station Concurrent Sessions Exit BMps
13020 //P2P Mode will be taken care in Open/close adapter
13021 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053013022 (vos_concurrent_open_sessions_running())) {
13023 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
13024 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053013025 }
13026
13027 /*Try disconnecting if already in connected state*/
13028 status = wlan_hdd_try_disconnect(pAdapter);
13029 if ( 0 > status)
13030 {
13031 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
13032 " connection"));
13033 return -EALREADY;
13034 }
13035
Jeff Johnson295189b2012-06-20 16:38:30 -070013036 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013037 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070013038
13039 if ( 0 > status)
13040 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013041 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070013042 __func__);
13043 return status;
13044 }
Mohit Khanna765234a2012-09-11 15:08:35 -070013045 if ( req->channel )
13046 {
13047 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
13048 req->ssid_len, req->bssid,
13049 req->channel->hw_value);
13050 }
13051 else
13052 {
13053 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013054 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070013055 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013056
Sushant Kaushikd7083982015-03-18 14:33:24 +053013057 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013058 {
13059 //ReEnable BMPS if disabled
13060 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
13061 (NULL != pHddCtx))
13062 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053013063 if (pHddCtx->hdd_wlan_suspended)
13064 {
13065 hdd_set_pwrparams(pHddCtx);
13066 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013067 //ReEnable Bmps and Imps back
13068 hdd_enable_bmps_imps(pHddCtx);
13069 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053013070 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070013071 return status;
13072 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013073 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013074 EXIT();
13075 return status;
13076}
13077
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013078static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
13079 struct net_device *ndev,
13080 struct cfg80211_connect_params *req)
13081{
13082 int ret;
13083 vos_ssr_protect(__func__);
13084 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
13085 vos_ssr_unprotect(__func__);
13086
13087 return ret;
13088}
Jeff Johnson295189b2012-06-20 16:38:30 -070013089
13090/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013091 * FUNCTION: wlan_hdd_disconnect
13092 * This function is used to issue a disconnect request to SME
13093 */
13094int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
13095{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013096 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013097 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013098 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013099 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013100
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013101 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013102
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013103 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013104 if (0 != status)
13105 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013106 return status;
13107 }
13108
Sushant Kaushikb4834d22015-07-15 15:29:05 +053013109 if (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)
13110 {
13111 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
13112 pAdapter->sessionId);
13113 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013114 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013115
Agarwal Ashish47d18112014-08-04 19:55:07 +053013116 /* Need to apply spin lock before decreasing active sessions
13117 * as there can be chance for double decrement if context switch
13118 * Calls hdd_DisConnectHandler.
13119 */
13120
13121 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013122 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
13123 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013124 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
13125 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053013126 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
13127 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053013128
Abhishek Singhf4669da2014-05-26 15:07:49 +053013129 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053013130 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
13131
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013132 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013133
Mihir Shete182a0b22014-08-18 16:08:48 +053013134 /*
13135 * stop tx queues before deleting STA/BSS context from the firmware.
13136 * tx has to be disabled because the firmware can get busy dropping
13137 * the tx frames after BSS/STA has been deleted and will not send
13138 * back a response resulting in WDI timeout
13139 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053013140 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053013141 netif_tx_disable(pAdapter->dev);
13142 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013143
Mihir Shete182a0b22014-08-18 16:08:48 +053013144 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013145 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
13146 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013147 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
13148 {
13149 hddLog(VOS_TRACE_LEVEL_INFO,
13150 FL("status = %d, already disconnected"),
13151 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013152
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013153 }
13154 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013155 {
13156 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013157 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013158 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013159 result = -EINVAL;
13160 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013161 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013162 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013163 &pAdapter->disconnect_comp_var,
13164 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013165 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013166 {
13167 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013168 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013169 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013170 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013171 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053013172 {
13173 hddLog(VOS_TRACE_LEVEL_ERROR,
13174 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013175 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013176 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013177disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053013178 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13179 FL("Set HDD connState to eConnectionState_NotConnected"));
13180 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
13181
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013182 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053013183 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013184}
13185
13186
13187/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013188 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070013189 * This function is used to issue a disconnect request to SME
13190 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013191static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013192 struct net_device *dev,
13193 u16 reason
13194 )
13195{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013196 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013197 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013198 tCsrRoamProfile *pRoamProfile;
13199 hdd_station_ctx_t *pHddStaCtx;
13200 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013201#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013202 tANI_U8 staIdx;
13203#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013204
Jeff Johnson295189b2012-06-20 16:38:30 -070013205 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013206
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013207 if (!pAdapter) {
13208 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
13209 return -EINVAL;
13210 }
13211
13212 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13213 if (!pHddStaCtx) {
13214 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
13215 return -EINVAL;
13216 }
13217
13218 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13219 status = wlan_hdd_validate_context(pHddCtx);
13220 if (0 != status)
13221 {
13222 return status;
13223 }
13224
13225 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
13226
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013227 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13228 TRACE_CODE_HDD_CFG80211_DISCONNECT,
13229 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013230 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
13231 __func__, hdd_device_modetoString(pAdapter->device_mode),
13232 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013233
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013234 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
13235 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070013236
Jeff Johnson295189b2012-06-20 16:38:30 -070013237 if (NULL != pRoamProfile)
13238 {
13239 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053013240 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
13241 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070013242 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013243 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070013244 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013245 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070013246 switch(reason)
13247 {
13248 case WLAN_REASON_MIC_FAILURE:
13249 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
13250 break;
13251
13252 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
13253 case WLAN_REASON_DISASSOC_AP_BUSY:
13254 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
13255 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
13256 break;
13257
13258 case WLAN_REASON_PREV_AUTH_NOT_VALID:
13259 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053013260 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070013261 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
13262 break;
13263
Jeff Johnson295189b2012-06-20 16:38:30 -070013264 default:
13265 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
13266 break;
13267 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013268 pScanInfo = &pHddCtx->scan_info;
13269 if (pScanInfo->mScanPending)
13270 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053013271 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013272 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013273 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053013274 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013275 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053013276 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013277#ifdef FEATURE_WLAN_TDLS
13278 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013279 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013280 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013281 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
13282 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013283 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013284 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013285 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053013286 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013287 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013288 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013289 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053013290 status = sme_DeleteTdlsPeerSta(
13291 WLAN_HDD_GET_HAL_CTX(pAdapter),
13292 pAdapter->sessionId,
13293 mac);
13294 if (status != eHAL_STATUS_SUCCESS) {
13295 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
13296 return -EPERM;
13297 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013298 }
13299 }
13300#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013301 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013302 status = wlan_hdd_disconnect(pAdapter, reasonCode);
13303 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070013304 {
13305 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013306 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013307 __func__, (int)status );
13308 return -EINVAL;
13309 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013310 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053013311 else
13312 {
13313 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
13314 "called while in %d state", __func__,
13315 pHddStaCtx->conn_info.connState);
13316 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013317 }
13318 else
13319 {
13320 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
13321 }
13322
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013323 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013324 return status;
13325}
13326
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013327static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
13328 struct net_device *dev,
13329 u16 reason
13330 )
13331{
13332 int ret;
13333 vos_ssr_protect(__func__);
13334 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
13335 vos_ssr_unprotect(__func__);
13336
13337 return ret;
13338}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013339
Jeff Johnson295189b2012-06-20 16:38:30 -070013340/*
13341 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013342 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070013343 * settings in IBSS mode.
13344 */
13345static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013346 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013347 struct cfg80211_ibss_params *params
13348 )
13349{
13350 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013351 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013352 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13353 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013354
Jeff Johnson295189b2012-06-20 16:38:30 -070013355 ENTER();
13356
13357 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070013358 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070013359
13360 if (params->ie_len && ( NULL != params->ie) )
13361 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013362 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
13363 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070013364 {
13365 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
13366 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13367 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013368 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070013369 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013370 tDot11fIEWPA dot11WPAIE;
13371 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013372 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013373
Wilson Yang00256342013-10-10 23:13:38 -070013374 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013375 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
13376 params->ie_len, DOT11F_EID_WPA);
13377 if ( NULL != ie )
13378 {
13379 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
13380 // Unpack the WPA IE
13381 //Skip past the EID byte and length byte - and four byte WiFi OUI
13382 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
13383 &ie[2+4],
13384 ie[1] - 4,
13385 &dot11WPAIE);
13386 /*Extract the multicast cipher, the encType for unicast
13387 cipher for wpa-none is none*/
13388 encryptionType =
13389 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
13390 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013391 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013392
Jeff Johnson295189b2012-06-20 16:38:30 -070013393 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
13394
13395 if (0 > status)
13396 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013397 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070013398 __func__);
13399 return status;
13400 }
13401 }
13402
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013403 pWextState->roamProfile.AuthType.authType[0] =
13404 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070013405 eCSR_AUTH_TYPE_OPEN_SYSTEM;
13406
13407 if (params->privacy)
13408 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013409 /* Security enabled IBSS, At this time there is no information available
13410 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070013411 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013412 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070013413 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013414 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070013415 *enable privacy bit in beacons */
13416
13417 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13418 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013419 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
13420 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070013421 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13422 pWextState->roamProfile.EncryptionType.numEntries = 1;
13423 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070013424 return status;
13425}
13426
13427/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013428 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013429 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070013430 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013431static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013432 struct net_device *dev,
13433 struct cfg80211_ibss_params *params
13434 )
13435{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013436 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013437 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13438 tCsrRoamProfile *pRoamProfile;
13439 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013440 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13441 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013442 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070013443
13444 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013445
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013446 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13447 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
13448 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013449 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013450 "%s: device_mode = %s (%d)", __func__,
13451 hdd_device_modetoString(pAdapter->device_mode),
13452 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013453
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013454 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013455 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013456 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013457 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013458 }
13459
13460 if (NULL == pWextState)
13461 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013462 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070013463 __func__);
13464 return -EIO;
13465 }
13466
Agarwal Ashish51325b52014-06-16 16:50:49 +053013467 if (vos_max_concurrent_connections_reached()) {
13468 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
13469 return -ECONNREFUSED;
13470 }
13471
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053013472 /*Try disconnecting if already in connected state*/
13473 status = wlan_hdd_try_disconnect(pAdapter);
13474 if ( 0 > status)
13475 {
13476 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
13477 " IBSS connection"));
13478 return -EALREADY;
13479 }
13480
Jeff Johnson295189b2012-06-20 16:38:30 -070013481 pRoamProfile = &pWextState->roamProfile;
13482
13483 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
13484 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013485 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013486 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013487 return -EINVAL;
13488 }
13489
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013490 /* BSSID is provided by upper layers hence no need to AUTO generate */
13491 if (NULL != params->bssid) {
13492 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
13493 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
13494 hddLog (VOS_TRACE_LEVEL_ERROR,
13495 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
13496 return -EIO;
13497 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013498 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013499 }
krunal sonie9002db2013-11-25 14:24:17 -080013500 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
13501 {
13502 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
13503 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
13504 {
13505 hddLog (VOS_TRACE_LEVEL_ERROR,
13506 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
13507 return -EIO;
13508 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013509
13510 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080013511 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013512 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080013513 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013514
Jeff Johnson295189b2012-06-20 16:38:30 -070013515 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070013516 if (NULL !=
13517#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
13518 params->chandef.chan)
13519#else
13520 params->channel)
13521#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013522 {
13523 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013524 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
13525 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
13526 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13527 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013528
13529 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013530 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070013531 ieee80211_frequency_to_channel(
13532#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
13533 params->chandef.chan->center_freq);
13534#else
13535 params->channel->center_freq);
13536#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013537
13538 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
13539 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070013540 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013541 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
13542 __func__);
13543 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070013544 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013545
13546 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013547 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013548 if (channelNum == validChan[indx])
13549 {
13550 break;
13551 }
13552 }
13553 if (indx >= numChans)
13554 {
13555 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013556 __func__, channelNum);
13557 return -EINVAL;
13558 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013559 /* Set the Operational Channel */
13560 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
13561 channelNum);
13562 pRoamProfile->ChannelInfo.numOfChannels = 1;
13563 pHddStaCtx->conn_info.operationChannel = channelNum;
13564 pRoamProfile->ChannelInfo.ChannelList =
13565 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070013566 }
13567
13568 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013569 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070013570 if (status < 0)
13571 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013572 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070013573 __func__);
13574 return status;
13575 }
13576
13577 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013578 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013579 params->ssid_len, params->bssid,
13580 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013581
13582 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013583 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013584
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013585 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013586 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013587}
13588
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013589static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
13590 struct net_device *dev,
13591 struct cfg80211_ibss_params *params
13592 )
13593{
13594 int ret = 0;
13595
13596 vos_ssr_protect(__func__);
13597 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
13598 vos_ssr_unprotect(__func__);
13599
13600 return ret;
13601}
13602
Jeff Johnson295189b2012-06-20 16:38:30 -070013603/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013604 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013605 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070013606 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013607static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013608 struct net_device *dev
13609 )
13610{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013611 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013612 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13613 tCsrRoamProfile *pRoamProfile;
13614 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013615 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013616
13617 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013618
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013619 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13620 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
13621 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013622 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013623 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013624 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013625 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013626 }
13627
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013628 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
13629 hdd_device_modetoString(pAdapter->device_mode),
13630 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013631 if (NULL == pWextState)
13632 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013633 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070013634 __func__);
13635 return -EIO;
13636 }
13637
13638 pRoamProfile = &pWextState->roamProfile;
13639
13640 /* Issue disconnect only if interface type is set to IBSS */
13641 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
13642 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013643 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070013644 __func__);
13645 return -EINVAL;
13646 }
13647
13648 /* Issue Disconnect request */
13649 INIT_COMPLETION(pAdapter->disconnect_comp_var);
13650 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
13651 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
13652
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013653 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013654 return 0;
13655}
13656
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013657static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
13658 struct net_device *dev
13659 )
13660{
13661 int ret = 0;
13662
13663 vos_ssr_protect(__func__);
13664 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
13665 vos_ssr_unprotect(__func__);
13666
13667 return ret;
13668}
13669
Jeff Johnson295189b2012-06-20 16:38:30 -070013670/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013671 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070013672 * This function is used to set the phy parameters
13673 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
13674 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013675static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013676 u32 changed)
13677{
13678 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13679 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013680 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013681
13682 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013683
13684 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013685 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
13686 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013687
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013688 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013689 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013690 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013691 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013692 }
13693
Jeff Johnson295189b2012-06-20 16:38:30 -070013694 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
13695 {
13696 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
13697 WNI_CFG_RTS_THRESHOLD_STAMAX :
13698 wiphy->rts_threshold;
13699
13700 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013701 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070013702 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013703 hddLog(VOS_TRACE_LEVEL_ERROR,
13704 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013705 __func__, rts_threshold);
13706 return -EINVAL;
13707 }
13708
13709 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
13710 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013711 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013712 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013713 hddLog(VOS_TRACE_LEVEL_ERROR,
13714 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013715 __func__, rts_threshold);
13716 return -EIO;
13717 }
13718
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013719 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013720 rts_threshold);
13721 }
13722
13723 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
13724 {
13725 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
13726 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
13727 wiphy->frag_threshold;
13728
13729 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013730 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013731 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013732 hddLog(VOS_TRACE_LEVEL_ERROR,
13733 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013734 frag_threshold);
13735 return -EINVAL;
13736 }
13737
13738 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
13739 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013740 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013741 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013742 hddLog(VOS_TRACE_LEVEL_ERROR,
13743 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013744 __func__, frag_threshold);
13745 return -EIO;
13746 }
13747
13748 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
13749 frag_threshold);
13750 }
13751
13752 if ((changed & WIPHY_PARAM_RETRY_SHORT)
13753 || (changed & WIPHY_PARAM_RETRY_LONG))
13754 {
13755 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
13756 wiphy->retry_short :
13757 wiphy->retry_long;
13758
13759 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
13760 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
13761 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013762 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013763 __func__, retry_value);
13764 return -EINVAL;
13765 }
13766
13767 if (changed & WIPHY_PARAM_RETRY_SHORT)
13768 {
13769 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
13770 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013771 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013772 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013773 hddLog(VOS_TRACE_LEVEL_ERROR,
13774 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013775 __func__, retry_value);
13776 return -EIO;
13777 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013778 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013779 __func__, retry_value);
13780 }
13781 else if (changed & WIPHY_PARAM_RETRY_SHORT)
13782 {
13783 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
13784 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013785 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013786 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013787 hddLog(VOS_TRACE_LEVEL_ERROR,
13788 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013789 __func__, retry_value);
13790 return -EIO;
13791 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013792 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013793 __func__, retry_value);
13794 }
13795 }
13796
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013797 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013798 return 0;
13799}
13800
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013801static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
13802 u32 changed)
13803{
13804 int ret;
13805
13806 vos_ssr_protect(__func__);
13807 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
13808 vos_ssr_unprotect(__func__);
13809
13810 return ret;
13811}
13812
Jeff Johnson295189b2012-06-20 16:38:30 -070013813/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013814 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013815 * This function is used to set the txpower
13816 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013817static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013818#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13819 struct wireless_dev *wdev,
13820#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013821#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013822 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013823#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013824 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013825#endif
13826 int dbm)
13827{
13828 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013829 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013830 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13831 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013832 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013833
13834 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013835
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013836 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13837 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
13838 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013839 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013840 if (0 != status)
13841 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013842 return status;
13843 }
13844
13845 hHal = pHddCtx->hHal;
13846
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013847 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
13848 dbm, ccmCfgSetCallback,
13849 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013850 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013851 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013852 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
13853 return -EIO;
13854 }
13855
13856 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
13857 dbm);
13858
13859 switch(type)
13860 {
13861 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
13862 /* Fall through */
13863 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
13864 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
13865 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013866 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
13867 __func__);
13868 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013869 }
13870 break;
13871 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013872 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070013873 __func__);
13874 return -EOPNOTSUPP;
13875 break;
13876 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013877 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
13878 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070013879 return -EIO;
13880 }
13881
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013882 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013883 return 0;
13884}
13885
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013886static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
13887#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13888 struct wireless_dev *wdev,
13889#endif
13890#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13891 enum tx_power_setting type,
13892#else
13893 enum nl80211_tx_power_setting type,
13894#endif
13895 int dbm)
13896{
13897 int ret;
13898 vos_ssr_protect(__func__);
13899 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
13900#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13901 wdev,
13902#endif
13903#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13904 type,
13905#else
13906 type,
13907#endif
13908 dbm);
13909 vos_ssr_unprotect(__func__);
13910
13911 return ret;
13912}
13913
Jeff Johnson295189b2012-06-20 16:38:30 -070013914/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013915 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013916 * This function is used to read the txpower
13917 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013918static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013919#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13920 struct wireless_dev *wdev,
13921#endif
13922 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070013923{
13924
13925 hdd_adapter_t *pAdapter;
13926 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013927 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013928
Jeff Johnsone7245742012-09-05 17:12:55 -070013929 ENTER();
13930
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013931 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013932 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013933 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013934 *dbm = 0;
13935 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013936 }
13937
Jeff Johnson295189b2012-06-20 16:38:30 -070013938 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
13939 if (NULL == pAdapter)
13940 {
13941 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
13942 return -ENOENT;
13943 }
13944
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053013945 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13946 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
13947 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070013948 wlan_hdd_get_classAstats(pAdapter);
13949 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
13950
Jeff Johnsone7245742012-09-05 17:12:55 -070013951 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013952 return 0;
13953}
13954
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013955static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
13956#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13957 struct wireless_dev *wdev,
13958#endif
13959 int *dbm)
13960{
13961 int ret;
13962
13963 vos_ssr_protect(__func__);
13964 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
13965#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13966 wdev,
13967#endif
13968 dbm);
13969 vos_ssr_unprotect(__func__);
13970
13971 return ret;
13972}
13973
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013974static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013975#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13976 const u8* mac,
13977#else
13978 u8* mac,
13979#endif
13980 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070013981{
13982 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13983 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13984 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053013985 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070013986
13987 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
13988 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070013989
13990 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
13991 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
13992 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
13993 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
13994 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
13995 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
13996 tANI_U16 maxRate = 0;
13997 tANI_U16 myRate;
13998 tANI_U16 currentRate = 0;
13999 tANI_U8 maxSpeedMCS = 0;
14000 tANI_U8 maxMCSIdx = 0;
14001 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053014002 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070014003 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014004 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014005
Leo Chang6f8870f2013-03-26 18:11:36 -070014006#ifdef WLAN_FEATURE_11AC
14007 tANI_U32 vht_mcs_map;
14008 eDataRate11ACMaxMcs vhtMaxMcs;
14009#endif /* WLAN_FEATURE_11AC */
14010
Jeff Johnsone7245742012-09-05 17:12:55 -070014011 ENTER();
14012
Jeff Johnson295189b2012-06-20 16:38:30 -070014013 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
14014 (0 == ssidlen))
14015 {
14016 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
14017 " Invalid ssidlen, %d", __func__, ssidlen);
14018 /*To keep GUI happy*/
14019 return 0;
14020 }
14021
Mukul Sharma811205f2014-07-09 21:07:30 +053014022 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
14023 {
14024 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14025 "%s: Roaming in progress, so unable to proceed this request", __func__);
14026 return 0;
14027 }
14028
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014029 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014030 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014031 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014032 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014033 }
14034
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053014035 wlan_hdd_get_station_stats(pAdapter);
14036 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070014037
Kiet Lam3b17fc82013-09-27 05:24:08 +053014038 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
14039 sinfo->filled |= STATION_INFO_SIGNAL;
14040
c_hpothu09f19542014-05-30 21:53:31 +053014041 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053014042 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
14043 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053014044 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053014045 {
14046 rate_flags = pAdapter->maxRateFlags;
14047 }
c_hpothu44ff4e02014-05-08 00:13:57 +053014048
Jeff Johnson295189b2012-06-20 16:38:30 -070014049 //convert to the UI units of 100kbps
14050 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
14051
14052#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070014053 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 -070014054 sinfo->signal,
14055 pCfg->reportMaxLinkSpeed,
14056 myRate,
14057 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070014058 (int) pCfg->linkSpeedRssiMid,
14059 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070014060 (int) rate_flags,
14061 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070014062#endif //LINKSPEED_DEBUG_ENABLED
14063
14064 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
14065 {
14066 // we do not want to necessarily report the current speed
14067 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
14068 {
14069 // report the max possible speed
14070 rssidx = 0;
14071 }
14072 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
14073 {
14074 // report the max possible speed with RSSI scaling
14075 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
14076 {
14077 // report the max possible speed
14078 rssidx = 0;
14079 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070014080 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070014081 {
14082 // report middle speed
14083 rssidx = 1;
14084 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070014085 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
14086 {
14087 // report middle speed
14088 rssidx = 2;
14089 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014090 else
14091 {
14092 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070014093 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070014094 }
14095 }
14096 else
14097 {
14098 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
14099 hddLog(VOS_TRACE_LEVEL_ERROR,
14100 "%s: Invalid value for reportMaxLinkSpeed: %u",
14101 __func__, pCfg->reportMaxLinkSpeed);
14102 rssidx = 0;
14103 }
14104
14105 maxRate = 0;
14106
14107 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053014108 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
14109 OperationalRates, &ORLeng))
14110 {
14111 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
14112 /*To keep GUI happy*/
14113 return 0;
14114 }
14115
Jeff Johnson295189b2012-06-20 16:38:30 -070014116 for (i = 0; i < ORLeng; i++)
14117 {
Jeff Johnsone7245742012-09-05 17:12:55 -070014118 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070014119 {
14120 /* Validate Rate Set */
14121 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
14122 {
14123 currentRate = supported_data_rate[j].supported_rate[rssidx];
14124 break;
14125 }
14126 }
14127 /* Update MAX rate */
14128 maxRate = (currentRate > maxRate)?currentRate:maxRate;
14129 }
14130
14131 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053014132 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
14133 ExtendedRates, &ERLeng))
14134 {
14135 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
14136 /*To keep GUI happy*/
14137 return 0;
14138 }
14139
Jeff Johnson295189b2012-06-20 16:38:30 -070014140 for (i = 0; i < ERLeng; i++)
14141 {
Jeff Johnsone7245742012-09-05 17:12:55 -070014142 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070014143 {
14144 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
14145 {
14146 currentRate = supported_data_rate[j].supported_rate[rssidx];
14147 break;
14148 }
14149 }
14150 /* Update MAX rate */
14151 maxRate = (currentRate > maxRate)?currentRate:maxRate;
14152 }
c_hpothu79aab322014-07-14 21:11:01 +053014153
Kiet Lamb69f8dc2013-11-15 15:34:27 +053014154 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053014155 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053014156 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053014157 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070014158 {
c_hpothu79aab322014-07-14 21:11:01 +053014159 if (rate_flags & eHAL_TX_RATE_VHT80)
14160 mode = 2;
14161 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
14162 mode = 1;
14163 else
14164 mode = 0;
14165
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053014166 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
14167 MCSRates, &MCSLeng))
14168 {
14169 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
14170 /*To keep GUI happy*/
14171 return 0;
14172 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014173 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070014174#ifdef WLAN_FEATURE_11AC
14175 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014176 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070014177 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014178 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014179 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070014180 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070014181 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014182 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070014183 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014184 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070014185 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014186 maxMCSIdx = 7;
14187 }
14188 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
14189 {
14190 maxMCSIdx = 8;
14191 }
14192 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
14193 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014194 //VHT20 is supporting 0~8
14195 if (rate_flags & eHAL_TX_RATE_VHT20)
14196 maxMCSIdx = 8;
14197 else
14198 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070014199 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014200
c_hpothu79aab322014-07-14 21:11:01 +053014201 if (0 != rssidx)/*check for scaled */
14202 {
14203 //get middle rate MCS index if rssi=1/2
14204 for (i=0; i <= maxMCSIdx; i++)
14205 {
14206 if (sinfo->signal <= rssiMcsTbl[mode][i])
14207 {
14208 maxMCSIdx = i;
14209 break;
14210 }
14211 }
14212 }
14213
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014214 if (rate_flags & eHAL_TX_RATE_VHT80)
14215 {
14216 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
14217 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
14218 }
14219 else if (rate_flags & eHAL_TX_RATE_VHT40)
14220 {
14221 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
14222 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
14223 }
14224 else if (rate_flags & eHAL_TX_RATE_VHT20)
14225 {
14226 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
14227 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
14228 }
14229
Leo Chang6f8870f2013-03-26 18:11:36 -070014230 maxSpeedMCS = 1;
14231 if (currentRate > maxRate)
14232 {
14233 maxRate = currentRate;
14234 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014235
Leo Chang6f8870f2013-03-26 18:11:36 -070014236 }
14237 else
14238#endif /* WLAN_FEATURE_11AC */
14239 {
14240 if (rate_flags & eHAL_TX_RATE_HT40)
14241 {
14242 rateFlag |= 1;
14243 }
14244 if (rate_flags & eHAL_TX_RATE_SGI)
14245 {
14246 rateFlag |= 2;
14247 }
14248
Girish Gowli01abcee2014-07-31 20:18:55 +053014249 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053014250 if (rssidx == 1 || rssidx == 2)
14251 {
14252 //get middle rate MCS index if rssi=1/2
14253 for (i=0; i <= 7; i++)
14254 {
14255 if (sinfo->signal <= rssiMcsTbl[mode][i])
14256 {
14257 temp = i+1;
14258 break;
14259 }
14260 }
14261 }
c_hpothu79aab322014-07-14 21:11:01 +053014262
14263 for (i = 0; i < MCSLeng; i++)
14264 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014265 for (j = 0; j < temp; j++)
14266 {
14267 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
14268 {
14269 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053014270 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070014271 break;
14272 }
14273 }
14274 if ((j < temp) && (currentRate > maxRate))
14275 {
14276 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070014277 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014278 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053014279 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070014280 }
14281 }
14282
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014283 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
14284 {
14285 maxRate = myRate;
14286 maxSpeedMCS = 1;
14287 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
14288 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014289 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053014290 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070014291 {
14292 maxRate = myRate;
14293 if (rate_flags & eHAL_TX_RATE_LEGACY)
14294 {
14295 maxSpeedMCS = 0;
14296 }
14297 else
14298 {
14299 maxSpeedMCS = 1;
14300 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
14301 }
14302 }
14303
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014304 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070014305 {
14306 sinfo->txrate.legacy = maxRate;
14307#ifdef LINKSPEED_DEBUG_ENABLED
14308 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
14309#endif //LINKSPEED_DEBUG_ENABLED
14310 }
14311 else
14312 {
14313 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070014314#ifdef WLAN_FEATURE_11AC
14315 sinfo->txrate.nss = 1;
14316 if (rate_flags & eHAL_TX_RATE_VHT80)
14317 {
14318 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014319 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070014320 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014321 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070014322 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014323 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14324 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14325 }
14326 else if (rate_flags & eHAL_TX_RATE_VHT20)
14327 {
14328 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14329 }
14330#endif /* WLAN_FEATURE_11AC */
14331 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
14332 {
14333 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
14334 if (rate_flags & eHAL_TX_RATE_HT40)
14335 {
14336 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14337 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014338 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014339 if (rate_flags & eHAL_TX_RATE_SGI)
14340 {
14341 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
14342 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014343
Jeff Johnson295189b2012-06-20 16:38:30 -070014344#ifdef LINKSPEED_DEBUG_ENABLED
14345 pr_info("Reporting MCS rate %d flags %x\n",
14346 sinfo->txrate.mcs,
14347 sinfo->txrate.flags );
14348#endif //LINKSPEED_DEBUG_ENABLED
14349 }
14350 }
14351 else
14352 {
14353 // report current rate instead of max rate
14354
14355 if (rate_flags & eHAL_TX_RATE_LEGACY)
14356 {
14357 //provide to the UI in units of 100kbps
14358 sinfo->txrate.legacy = myRate;
14359#ifdef LINKSPEED_DEBUG_ENABLED
14360 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
14361#endif //LINKSPEED_DEBUG_ENABLED
14362 }
14363 else
14364 {
14365 //must be MCS
14366 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070014367#ifdef WLAN_FEATURE_11AC
14368 sinfo->txrate.nss = 1;
14369 if (rate_flags & eHAL_TX_RATE_VHT80)
14370 {
14371 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14372 }
14373 else
14374#endif /* WLAN_FEATURE_11AC */
14375 {
14376 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
14377 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014378 if (rate_flags & eHAL_TX_RATE_SGI)
14379 {
14380 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
14381 }
14382 if (rate_flags & eHAL_TX_RATE_HT40)
14383 {
14384 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14385 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014386#ifdef WLAN_FEATURE_11AC
14387 else if (rate_flags & eHAL_TX_RATE_VHT80)
14388 {
14389 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
14390 }
14391#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070014392#ifdef LINKSPEED_DEBUG_ENABLED
14393 pr_info("Reporting actual MCS rate %d flags %x\n",
14394 sinfo->txrate.mcs,
14395 sinfo->txrate.flags );
14396#endif //LINKSPEED_DEBUG_ENABLED
14397 }
14398 }
14399 sinfo->filled |= STATION_INFO_TX_BITRATE;
14400
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070014401 sinfo->tx_packets =
14402 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
14403 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
14404 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
14405 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
14406
14407 sinfo->tx_retries =
14408 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
14409 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
14410 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
14411 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
14412
14413 sinfo->tx_failed =
14414 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
14415 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
14416 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
14417 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
14418
14419 sinfo->filled |=
14420 STATION_INFO_TX_PACKETS |
14421 STATION_INFO_TX_RETRIES |
14422 STATION_INFO_TX_FAILED;
14423
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014424 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14425 TRACE_CODE_HDD_CFG80211_GET_STA,
14426 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070014427 EXIT();
14428 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014429}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014430#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14431static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
14432 const u8* mac, struct station_info *sinfo)
14433#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014434static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
14435 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014436#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014437{
14438 int ret;
14439
14440 vos_ssr_protect(__func__);
14441 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
14442 vos_ssr_unprotect(__func__);
14443
14444 return ret;
14445}
14446
14447static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070014448 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070014449{
14450 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014451 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014452 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014453 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014454
Jeff Johnsone7245742012-09-05 17:12:55 -070014455 ENTER();
14456
Jeff Johnson295189b2012-06-20 16:38:30 -070014457 if (NULL == pAdapter)
14458 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014459 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014460 return -ENODEV;
14461 }
14462
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014463 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14464 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
14465 pAdapter->sessionId, timeout));
14466
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014467 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014468 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014469 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014470 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014471 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014472 }
14473
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014474 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
14475 (TRUE == pHddCtx->hdd_wlan_suspended) &&
14476 (pHddCtx->cfg_ini->fhostArpOffload) &&
14477 (eConnectionState_Associated ==
14478 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
14479 {
Amar Singhald53568e2013-09-26 11:03:45 -070014480
14481 hddLog(VOS_TRACE_LEVEL_INFO,
14482 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053014483 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014484 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14485 {
14486 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014487 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014488 __func__, vos_status);
14489 }
14490 }
14491
Jeff Johnson295189b2012-06-20 16:38:30 -070014492 /**The get power cmd from the supplicant gets updated by the nl only
14493 *on successful execution of the function call
14494 *we are oppositely mapped w.r.t mode in the driver
14495 **/
14496 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
14497
14498 if (VOS_STATUS_E_FAILURE == vos_status)
14499 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014500 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14501 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014502 return -EINVAL;
14503 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014504 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014505 return 0;
14506}
14507
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014508static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
14509 struct net_device *dev, bool mode, int timeout)
14510{
14511 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014512
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014513 vos_ssr_protect(__func__);
14514 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
14515 vos_ssr_unprotect(__func__);
14516
14517 return ret;
14518}
Jeff Johnson295189b2012-06-20 16:38:30 -070014519#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014520static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
14521 struct net_device *netdev,
14522 u8 key_index)
14523{
14524 ENTER();
14525 return 0;
14526}
14527
Jeff Johnson295189b2012-06-20 16:38:30 -070014528static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014529 struct net_device *netdev,
14530 u8 key_index)
14531{
14532 int ret;
14533 vos_ssr_protect(__func__);
14534 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
14535 vos_ssr_unprotect(__func__);
14536 return ret;
14537}
14538#endif //LINUX_VERSION_CODE
14539
14540#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
14541static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
14542 struct net_device *dev,
14543 struct ieee80211_txq_params *params)
14544{
14545 ENTER();
14546 return 0;
14547}
14548#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14549static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
14550 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070014551{
Jeff Johnsone7245742012-09-05 17:12:55 -070014552 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070014553 return 0;
14554}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014555#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070014556
14557#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
14558static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014559 struct net_device *dev,
14560 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070014561{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014562 int ret;
14563
14564 vos_ssr_protect(__func__);
14565 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
14566 vos_ssr_unprotect(__func__);
14567 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014568}
14569#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14570static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
14571 struct ieee80211_txq_params *params)
14572{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014573 int ret;
14574
14575 vos_ssr_protect(__func__);
14576 ret = __wlan_hdd_set_txq_params(wiphy, params);
14577 vos_ssr_unprotect(__func__);
14578 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014579}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014580#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014581
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014582static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014583 struct net_device *dev,
14584 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070014585{
14586 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014587 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014588 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014589 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014590 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014591 v_CONTEXT_t pVosContext = NULL;
14592 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014593
Jeff Johnsone7245742012-09-05 17:12:55 -070014594 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014595
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014596 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070014597 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014598 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014599 return -EINVAL;
14600 }
14601
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014602 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14603 TRACE_CODE_HDD_CFG80211_DEL_STA,
14604 pAdapter->sessionId, pAdapter->device_mode));
14605
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014606 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14607 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014608 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014609 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014610 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014611 }
14612
Jeff Johnson295189b2012-06-20 16:38:30 -070014613 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014614 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014615 )
14616 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014617 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14618 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14619 if(pSapCtx == NULL){
14620 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14621 FL("psapCtx is NULL"));
14622 return -ENOENT;
14623 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014624 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070014625 {
14626 v_U16_t i;
14627 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
14628 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014629 if ((pSapCtx->aStaInfo[i].isUsed) &&
14630 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070014631 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014632 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014633 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014634 ETHER_ADDR_LEN);
14635
Jeff Johnson295189b2012-06-20 16:38:30 -070014636 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014637 "%s: Delete STA with MAC::"
14638 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014639 __func__,
14640 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
14641 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070014642 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014643 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014644 }
14645 }
14646 }
14647 else
14648 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014649
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014650 vos_status = hdd_softap_GetStaId(pAdapter,
14651 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014652 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14653 {
14654 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014655 "%s: Skip this DEL STA as this is not used::"
14656 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014657 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014658 return -ENOENT;
14659 }
14660
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014661 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014662 {
14663 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014664 "%s: Skip this DEL STA as deauth is in progress::"
14665 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014666 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014667 return -ENOENT;
14668 }
14669
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014670 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014671
Jeff Johnson295189b2012-06-20 16:38:30 -070014672 hddLog(VOS_TRACE_LEVEL_INFO,
14673 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080014674 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014675 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014676 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014677
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014678 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014679 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14680 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014681 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014682 hddLog(VOS_TRACE_LEVEL_INFO,
14683 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080014684 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014685 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014686 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014687 return -ENOENT;
14688 }
14689
Jeff Johnson295189b2012-06-20 16:38:30 -070014690 }
14691 }
14692
14693 EXIT();
14694
14695 return 0;
14696}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014697
14698#ifdef CFG80211_DEL_STA_V2
14699static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14700 struct net_device *dev,
14701 struct station_del_parameters *param)
14702#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014703#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14704static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14705 struct net_device *dev, const u8 *mac)
14706#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014707static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14708 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014709#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014710#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014711{
14712 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014713 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070014714
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014715 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014716
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014717#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014718 if (NULL == param) {
14719 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014720 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014721 return -EINVAL;
14722 }
14723
14724 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
14725 param->subtype, &delStaParams);
14726
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014727#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053014728 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014729 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014730#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014731 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
14732
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014733 vos_ssr_unprotect(__func__);
14734
14735 return ret;
14736}
14737
14738static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014739 struct net_device *dev,
14740#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14741 const u8 *mac,
14742#else
14743 u8 *mac,
14744#endif
14745 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014746{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014747 hdd_adapter_t *pAdapter;
14748 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014749 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014750#ifdef FEATURE_WLAN_TDLS
14751 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014752
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014753 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014754
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014755 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14756 if (NULL == pAdapter)
14757 {
14758 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14759 "%s: Adapter is NULL",__func__);
14760 return -EINVAL;
14761 }
14762 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14763 status = wlan_hdd_validate_context(pHddCtx);
14764 if (0 != status)
14765 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014766 return status;
14767 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014768
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014769 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14770 TRACE_CODE_HDD_CFG80211_ADD_STA,
14771 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014772 mask = params->sta_flags_mask;
14773
14774 set = params->sta_flags_set;
14775
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014776 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014777 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
14778 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014779
14780 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
14781 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014782 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014783 }
14784 }
14785#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014786 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014787 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014788}
14789
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014790#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14791static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14792 struct net_device *dev, const u8 *mac,
14793 struct station_parameters *params)
14794#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014795static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14796 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014797#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014798{
14799 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014800
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014801 vos_ssr_protect(__func__);
14802 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
14803 vos_ssr_unprotect(__func__);
14804
14805 return ret;
14806}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014807#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070014808
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014809static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070014810 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014811{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014812 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14813 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014814 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014815 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014816 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014817 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070014818
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014819 ENTER();
14820
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014821 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014822 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014823 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014824 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014825 return -EINVAL;
14826 }
14827
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014828 if (!pmksa) {
14829 hddLog(LOGE, FL("pmksa is NULL"));
14830 return -EINVAL;
14831 }
14832
14833 if (!pmksa->bssid || !pmksa->pmkid) {
14834 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
14835 pmksa->bssid, pmksa->pmkid);
14836 return -EINVAL;
14837 }
14838
14839 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
14840 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14841
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014842 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14843 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014844 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014845 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014846 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014847 }
14848
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014849 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014850 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14851
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014852 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
14853 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014854
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014855 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014856 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014857 &pmk_id, 1, FALSE);
14858
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014859 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14860 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
14861 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014862
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014863 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014864 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014865}
14866
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014867static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
14868 struct cfg80211_pmksa *pmksa)
14869{
14870 int ret;
14871
14872 vos_ssr_protect(__func__);
14873 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
14874 vos_ssr_unprotect(__func__);
14875
14876 return ret;
14877}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014878
Wilson Yang6507c4e2013-10-01 20:11:19 -070014879
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014880static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070014881 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014882{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014883 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14884 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014885 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014886 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014887
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014888 ENTER();
14889
Wilson Yang6507c4e2013-10-01 20:11:19 -070014890 /* Validate pAdapter */
14891 if (NULL == pAdapter)
14892 {
14893 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
14894 return -EINVAL;
14895 }
14896
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014897 if (!pmksa) {
14898 hddLog(LOGE, FL("pmksa is NULL"));
14899 return -EINVAL;
14900 }
14901
14902 if (!pmksa->bssid) {
14903 hddLog(LOGE, FL("pmksa->bssid is NULL"));
14904 return -EINVAL;
14905 }
14906
Kiet Lam98c46a12014-10-31 15:34:57 -070014907 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
14908 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14909
Wilson Yang6507c4e2013-10-01 20:11:19 -070014910 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14911 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014912 if (0 != status)
14913 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014914 return status;
14915 }
14916
14917 /*Retrieve halHandle*/
14918 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14919
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014920 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14921 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
14922 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014923 /* Delete the PMKID CSR cache */
14924 if (eHAL_STATUS_SUCCESS !=
14925 sme_RoamDelPMKIDfromCache(halHandle,
14926 pAdapter->sessionId, pmksa->bssid, FALSE)) {
14927 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
14928 MAC_ADDR_ARRAY(pmksa->bssid));
14929 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014930 }
14931
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014932 EXIT();
14933 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014934}
14935
Wilson Yang6507c4e2013-10-01 20:11:19 -070014936
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014937static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
14938 struct cfg80211_pmksa *pmksa)
14939{
14940 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014941
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014942 vos_ssr_protect(__func__);
14943 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
14944 vos_ssr_unprotect(__func__);
14945
14946 return ret;
14947
14948}
14949
14950static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014951{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014952 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14953 tHalHandle halHandle;
14954 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014955 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014956
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014957 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070014958
14959 /* Validate pAdapter */
14960 if (NULL == pAdapter)
14961 {
14962 hddLog(VOS_TRACE_LEVEL_ERROR,
14963 "%s: Invalid Adapter" ,__func__);
14964 return -EINVAL;
14965 }
14966
14967 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14968 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014969 if (0 != status)
14970 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014971 return status;
14972 }
14973
14974 /*Retrieve halHandle*/
14975 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14976
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014977 /* Flush the PMKID cache in CSR */
14978 if (eHAL_STATUS_SUCCESS !=
14979 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
14980 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
14981 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014982 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014983 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080014984 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014985}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014986
14987static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
14988{
14989 int ret;
14990
14991 vos_ssr_protect(__func__);
14992 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
14993 vos_ssr_unprotect(__func__);
14994
14995 return ret;
14996}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014997#endif
14998
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014999#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015000static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
15001 struct net_device *dev,
15002 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015003{
15004 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15005 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015006 hdd_context_t *pHddCtx;
15007 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015008
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015009 ENTER();
15010
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015011 if (NULL == pAdapter)
15012 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015013 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015014 return -ENODEV;
15015 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015016 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15017 ret = wlan_hdd_validate_context(pHddCtx);
15018 if (0 != ret)
15019 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053015020 return ret;
15021 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015022 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015023 if (NULL == pHddStaCtx)
15024 {
15025 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
15026 return -EINVAL;
15027 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015028
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015029 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15030 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
15031 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015032 // Added for debug on reception of Re-assoc Req.
15033 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
15034 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080015035 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015036 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080015037 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015038 }
15039
15040#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080015041 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015042 ftie->ie_len);
15043#endif
15044
15045 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053015046 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
15047 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015048 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015049
15050 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015051 return 0;
15052}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015053
15054static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
15055 struct net_device *dev,
15056 struct cfg80211_update_ft_ies_params *ftie)
15057{
15058 int ret;
15059
15060 vos_ssr_protect(__func__);
15061 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
15062 vos_ssr_unprotect(__func__);
15063
15064 return ret;
15065}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070015066#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070015067
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015068#ifdef FEATURE_WLAN_SCAN_PNO
15069
15070void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
15071 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
15072{
15073 int ret;
15074 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
15075 hdd_context_t *pHddCtx;
15076
Nirav Shah80830bf2013-12-31 16:35:12 +053015077 ENTER();
15078
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015079 if (NULL == pAdapter)
15080 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053015081 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015082 "%s: HDD adapter is Null", __func__);
15083 return ;
15084 }
15085
15086 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15087 if (NULL == pHddCtx)
15088 {
15089 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15090 "%s: HDD context is Null!!!", __func__);
15091 return ;
15092 }
15093
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015094 spin_lock(&pHddCtx->schedScan_lock);
15095 if (TRUE == pHddCtx->isWiphySuspended)
15096 {
15097 pHddCtx->isSchedScanUpdatePending = TRUE;
15098 spin_unlock(&pHddCtx->schedScan_lock);
15099 hddLog(VOS_TRACE_LEVEL_INFO,
15100 "%s: Update cfg80211 scan database after it resume", __func__);
15101 return ;
15102 }
15103 spin_unlock(&pHddCtx->schedScan_lock);
15104
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015105 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
15106
15107 if (0 > ret)
15108 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
15109
15110 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015111 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15112 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015113}
15114
15115/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015116 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015117 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015118 */
15119static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
15120{
15121 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
15122 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015123 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015124 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15125 int status = 0;
15126 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
15127
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015128 /* The current firmware design does not allow PNO during any
15129 * active sessions. Hence, determine the active sessions
15130 * and return a failure.
15131 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015132 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
15133 {
15134 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015135 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015136
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015137 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
15138 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
15139 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
15140 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
15141 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053015142 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015143 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015144 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015145 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015146 }
15147 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
15148 pAdapterNode = pNext;
15149 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015150 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015151}
15152
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015153void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
15154{
15155 hdd_adapter_t *pAdapter = callbackContext;
15156 hdd_context_t *pHddCtx;
15157
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015158 ENTER();
15159
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015160 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
15161 {
15162 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15163 FL("Invalid adapter or adapter has invalid magic"));
15164 return;
15165 }
15166
15167 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15168 if (0 != wlan_hdd_validate_context(pHddCtx))
15169 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015170 return;
15171 }
15172
c_hpothub53c45d2014-08-18 16:53:14 +053015173 if (VOS_STATUS_SUCCESS != status)
15174 {
15175 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015176 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053015177 pHddCtx->isPnoEnable = FALSE;
15178 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015179
15180 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
15181 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015182 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015183}
15184
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015185/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015186 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
15187 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015188 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015189static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015190 struct net_device *dev, struct cfg80211_sched_scan_request *request)
15191{
15192 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015193 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015194 hdd_context_t *pHddCtx;
15195 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015196 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053015197 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
15198 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015199 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
15200 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015201 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015202 hdd_config_t *pConfig = NULL;
15203 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015204
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015205 ENTER();
15206
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015207 if (NULL == pAdapter)
15208 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015209 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015210 "%s: HDD adapter is Null", __func__);
15211 return -ENODEV;
15212 }
15213
15214 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015215 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015216
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015217 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015218 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015219 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015220 }
15221
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015222 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015223 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15224 if (NULL == hHal)
15225 {
15226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15227 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015228 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015229 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015230 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15231 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
15232 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053015233 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015234 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053015235 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015236 {
15237 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15238 "%s: aborting the existing scan is unsuccessfull", __func__);
15239 return -EBUSY;
15240 }
15241
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015242 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015243 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015244 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015245 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015246 return -EBUSY;
15247 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015248
c_hpothu37f21312014-04-09 21:49:54 +053015249 if (TRUE == pHddCtx->isPnoEnable)
15250 {
15251 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15252 FL("already PNO is enabled"));
15253 return -EBUSY;
15254 }
c_hpothu225aa7c2014-10-22 17:45:13 +053015255
15256 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
15257 {
15258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15259 "%s: abort ROC failed ", __func__);
15260 return -EBUSY;
15261 }
15262
c_hpothu37f21312014-04-09 21:49:54 +053015263 pHddCtx->isPnoEnable = TRUE;
15264
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015265 pnoRequest.enable = 1; /*Enable PNO */
15266 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015267
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015268 if (( !pnoRequest.ucNetworksCount ) ||
15269 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015270 {
15271 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015272 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015273 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015274 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015275 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015276 goto error;
15277 }
15278
15279 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
15280 {
15281 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015282 "%s: Incorrect number of channels %d",
15283 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015284 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015285 goto error;
15286 }
15287
15288 /* Framework provides one set of channels(all)
15289 * common for all saved profile */
15290 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
15291 channels_allowed, &num_channels_allowed))
15292 {
15293 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15294 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015295 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015296 goto error;
15297 }
15298 /* Checking each channel against allowed channel list */
15299 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053015300 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015301 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015302 char chList [(request->n_channels*5)+1];
15303 int len;
15304 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015305 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015306 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015307 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015308 if (request->channels[i]->hw_value == channels_allowed[indx])
15309 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015310 if ((!pConfig->enableDFSPnoChnlScan) &&
15311 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
15312 {
15313 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15314 "%s : Dropping DFS channel : %d",
15315 __func__,channels_allowed[indx]);
15316 num_ignore_dfs_ch++;
15317 break;
15318 }
15319
Nirav Shah80830bf2013-12-31 16:35:12 +053015320 valid_ch[num_ch++] = request->channels[i]->hw_value;
15321 len += snprintf(chList+len, 5, "%d ",
15322 request->channels[i]->hw_value);
15323 break ;
15324 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015325 }
15326 }
Nirav Shah80830bf2013-12-31 16:35:12 +053015327 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015328
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015329 /*If all channels are DFS and dropped, then ignore the PNO request*/
15330 if (num_ignore_dfs_ch == request->n_channels)
15331 {
15332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15333 "%s : All requested channels are DFS channels", __func__);
15334 ret = -EINVAL;
15335 goto error;
15336 }
15337 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015338
15339 pnoRequest.aNetworks =
15340 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15341 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015342 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015343 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15344 FL("failed to allocate memory aNetworks %u"),
15345 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15346 goto error;
15347 }
15348 vos_mem_zero(pnoRequest.aNetworks,
15349 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15350
15351 /* Filling per profile params */
15352 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
15353 {
15354 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015355 request->match_sets[i].ssid.ssid_len;
15356
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015357 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
15358 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015359 {
15360 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015361 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015362 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015363 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015364 goto error;
15365 }
15366
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015367 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015368 request->match_sets[i].ssid.ssid,
15369 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15371 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015372 i, pnoRequest.aNetworks[i].ssId.ssId);
15373 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
15374 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
15375 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015376
15377 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015378 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
15379 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015380
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015381 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015382 }
15383
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015384 for (i = 0; i < request->n_ssids; i++)
15385 {
15386 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015387 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015388 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015389 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015390 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015391 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015392 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015393 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015394 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015395 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015396 break;
15397 }
15398 j++;
15399 }
15400 }
15401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15402 "Number of hidden networks being Configured = %d",
15403 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080015405 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015406
15407 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
15408 if (pnoRequest.p24GProbeTemplate == NULL)
15409 {
15410 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15411 FL("failed to allocate memory p24GProbeTemplate %u"),
15412 SIR_PNO_MAX_PB_REQ_SIZE);
15413 goto error;
15414 }
15415
15416 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
15417 if (pnoRequest.p5GProbeTemplate == NULL)
15418 {
15419 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15420 FL("failed to allocate memory p5GProbeTemplate %u"),
15421 SIR_PNO_MAX_PB_REQ_SIZE);
15422 goto error;
15423 }
15424
15425 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
15426 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
15427
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053015428 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
15429 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015430 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015431 pnoRequest.us24GProbeTemplateLen = request->ie_len;
15432 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
15433 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015434
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015435 pnoRequest.us5GProbeTemplateLen = request->ie_len;
15436 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
15437 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015438 }
15439
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015440 /* Driver gets only one time interval which is hardcoded in
15441 * supplicant for 10000ms. Taking power consumption into account 6 timers
15442 * will be used, Timervalue is increased exponentially i.e 10,20,40,
15443 * 80,160,320 secs. And number of scan cycle for each timer
15444 * is configurable through INI param gPNOScanTimerRepeatValue.
15445 * If it is set to 0 only one timer will be used and PNO scan cycle
15446 * will be repeated after each interval specified by supplicant
15447 * till PNO is disabled.
15448 */
15449 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015450 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015451 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015452 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015453 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
15454
15455 tempInterval = (request->interval)/1000;
15456 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15457 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
15458 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015459 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015460 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015461 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015462 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015463 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015464 tempInterval *= 2;
15465 }
15466 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015467 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015468
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015469 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015470
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015471 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015472 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
15473 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015474 pAdapter->pno_req_status = 0;
15475
Nirav Shah80830bf2013-12-31 16:35:12 +053015476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15477 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015478 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
15479 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053015480
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015481 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015482 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015483 hdd_cfg80211_sched_scan_done_callback, pAdapter);
15484 if (eHAL_STATUS_SUCCESS != status)
15485 {
15486 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015487 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015488 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015489 goto error;
15490 }
15491
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015492 ret = wait_for_completion_timeout(
15493 &pAdapter->pno_comp_var,
15494 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
15495 if (0 >= ret)
15496 {
15497 // Did not receive the response for PNO enable in time.
15498 // Assuming the PNO enable was success.
15499 // Returning error from here, because we timeout, results
15500 // in side effect of Wifi (Wifi Setting) not to work.
15501 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15502 FL("Timed out waiting for PNO to be Enabled"));
15503 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015504 }
15505
15506 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053015507 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015508
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015509error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015510 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15511 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053015512 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015513 if (pnoRequest.aNetworks)
15514 vos_mem_free(pnoRequest.aNetworks);
15515 if (pnoRequest.p24GProbeTemplate)
15516 vos_mem_free(pnoRequest.p24GProbeTemplate);
15517 if (pnoRequest.p5GProbeTemplate)
15518 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015519
15520 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015521 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015522}
15523
15524/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015525 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
15526 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015527 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015528static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
15529 struct net_device *dev, struct cfg80211_sched_scan_request *request)
15530{
15531 int ret;
15532
15533 vos_ssr_protect(__func__);
15534 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
15535 vos_ssr_unprotect(__func__);
15536
15537 return ret;
15538}
15539
15540/*
15541 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
15542 * Function to disable PNO
15543 */
15544static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015545 struct net_device *dev)
15546{
15547 eHalStatus status = eHAL_STATUS_FAILURE;
15548 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15549 hdd_context_t *pHddCtx;
15550 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015551 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015552 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015553
15554 ENTER();
15555
15556 if (NULL == pAdapter)
15557 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015558 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015559 "%s: HDD adapter is Null", __func__);
15560 return -ENODEV;
15561 }
15562
15563 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015564
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015565 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015566 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015567 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015568 "%s: HDD context is Null", __func__);
15569 return -ENODEV;
15570 }
15571
15572 /* The return 0 is intentional when isLogpInProgress and
15573 * isLoadUnloadInProgress. We did observe a crash due to a return of
15574 * failure in sched_scan_stop , especially for a case where the unload
15575 * of the happens at the same time. The function __cfg80211_stop_sched_scan
15576 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
15577 * success. If it returns a failure , then its next invocation due to the
15578 * clean up of the second interface will have the dev pointer corresponding
15579 * to the first one leading to a crash.
15580 */
15581 if (pHddCtx->isLogpInProgress)
15582 {
15583 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15584 "%s: LOGP in Progress. Ignore!!!", __func__);
15585 return ret;
15586 }
15587
Mihir Shete18156292014-03-11 15:38:30 +053015588 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015589 {
15590 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15591 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15592 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015593 }
15594
15595 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15596 if (NULL == hHal)
15597 {
15598 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15599 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015600 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015601 }
15602
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015603 pnoRequest.enable = 0; /* Disable PNO */
15604 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015605
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015606 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15607 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
15608 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015609 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015610 pAdapter->sessionId,
15611 NULL, pAdapter);
15612 if (eHAL_STATUS_SUCCESS != status)
15613 {
15614 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15615 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015616 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015617 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015618 }
c_hpothu37f21312014-04-09 21:49:54 +053015619 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015620
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015621error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015622 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015623 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015624
15625 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015626 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015627}
15628
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015629/*
15630 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
15631 * NL interface to disable PNO
15632 */
15633static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
15634 struct net_device *dev)
15635{
15636 int ret;
15637
15638 vos_ssr_protect(__func__);
15639 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
15640 vos_ssr_unprotect(__func__);
15641
15642 return ret;
15643}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015644#endif /*FEATURE_WLAN_SCAN_PNO*/
15645
15646
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015647#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015648#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015649static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15650 struct net_device *dev,
15651 u8 *peer, u8 action_code,
15652 u8 dialog_token,
15653 u16 status_code, u32 peer_capability,
15654 const u8 *buf, size_t len)
15655#else /* TDLS_MGMT_VERSION2 */
15656#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
15657static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15658 struct net_device *dev,
15659 const u8 *peer, u8 action_code,
15660 u8 dialog_token, u16 status_code,
15661 u32 peer_capability, bool initiator,
15662 const u8 *buf, size_t len)
15663#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
15664static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15665 struct net_device *dev,
15666 const u8 *peer, u8 action_code,
15667 u8 dialog_token, u16 status_code,
15668 u32 peer_capability, const u8 *buf,
15669 size_t len)
15670#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
15671static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15672 struct net_device *dev,
15673 u8 *peer, u8 action_code,
15674 u8 dialog_token,
15675 u16 status_code, u32 peer_capability,
15676 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015677#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015678static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15679 struct net_device *dev,
15680 u8 *peer, u8 action_code,
15681 u8 dialog_token,
15682 u16 status_code, const u8 *buf,
15683 size_t len)
15684#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015685#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015686{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015687 hdd_adapter_t *pAdapter;
15688 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015689 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070015690 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080015691 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070015692 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015693 int ret;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015694#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015695 u32 peer_capability = 0;
15696#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015697 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015698 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015699
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015700 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15701 if (NULL == pAdapter)
15702 {
15703 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15704 "%s: Adapter is NULL",__func__);
15705 return -EINVAL;
15706 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015707 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15708 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
15709 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015710
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015711 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015712 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015713 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015715 "Invalid arguments");
15716 return -EINVAL;
15717 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015718
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015719 if (pHddCtx->isLogpInProgress)
15720 {
15721 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15722 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053015723 wlan_hdd_tdls_set_link_status(pAdapter,
15724 peer,
15725 eTDLS_LINK_IDLE,
15726 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015727 return -EBUSY;
15728 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015729
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015730 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
15731 {
15732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15733 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15734 return -EAGAIN;
15735 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015736
Hoonki Lee27511902013-03-14 18:19:06 -070015737 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015738 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015739 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015740 "%s: TDLS mode is disabled OR not enabled in FW."
15741 MAC_ADDRESS_STR " action %d declined.",
15742 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015743 return -ENOTSUPP;
15744 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015745
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015746 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15747
15748 if( NULL == pHddStaCtx )
15749 {
15750 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15751 "%s: HDD station context NULL ",__func__);
15752 return -EINVAL;
15753 }
15754
15755 /* STA should be connected and authenticated
15756 * before sending any TDLS frames
15757 */
15758 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15759 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
15760 {
15761 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15762 "STA is not connected or unauthenticated. "
15763 "connState %u, uIsAuthenticated %u",
15764 pHddStaCtx->conn_info.connState,
15765 pHddStaCtx->conn_info.uIsAuthenticated);
15766 return -EAGAIN;
15767 }
15768
Hoonki Lee27511902013-03-14 18:19:06 -070015769 /* other than teardown frame, other mgmt frames are not sent if disabled */
15770 if (SIR_MAC_TDLS_TEARDOWN != action_code)
15771 {
15772 /* if tdls_mode is disabled to respond to peer's request */
15773 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
15774 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015775 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015776 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015777 " TDLS mode is disabled. action %d declined.",
15778 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070015779
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015780 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070015781 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053015782
15783 if (vos_max_concurrent_connections_reached())
15784 {
15785 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15786 return -EINVAL;
15787 }
Hoonki Lee27511902013-03-14 18:19:06 -070015788 }
15789
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015790 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
15791 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053015792 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015793 {
15794 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015795 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015796 " TDLS setup is ongoing. action %d declined.",
15797 __func__, MAC_ADDR_ARRAY(peer), action_code);
15798 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015799 }
15800 }
15801
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015802 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
15803 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080015804 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015805 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15806 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015807 {
15808 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
15809 we return error code at 'add_station()'. Hence we have this
15810 check again in addtion to add_station().
15811 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015812 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015813 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015814 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15815 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015816 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
15817 __func__, MAC_ADDR_ARRAY(peer), action_code,
15818 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053015819 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080015820 }
15821 else
15822 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015823 /* maximum reached. tweak to send error code to peer and return
15824 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015825 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015826 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15827 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015828 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
15829 __func__, MAC_ADDR_ARRAY(peer), status_code,
15830 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070015831 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015832 /* fall through to send setup resp with failure status
15833 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015834 }
15835 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015836 else
15837 {
15838 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053015839 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015840 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015841 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015842 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015843 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
15844 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015845 return -EPERM;
15846 }
15847 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015848 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015849
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015850 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015851 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015852 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
15853 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015854
Hoonki Leea34dd892013-02-05 22:56:02 -080015855 /*Except teardown responder will not be used so just make 0*/
15856 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015857 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080015858 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015859
15860 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015861 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015862
15863 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
15864 responder = pTdlsPeer->is_responder;
15865 else
Hoonki Leea34dd892013-02-05 22:56:02 -080015866 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015867 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015868 "%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 -070015869 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
15870 dialog_token, status_code, len);
15871 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080015872 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015873 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015874
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015875 /* For explicit trigger of DIS_REQ come out of BMPS for
15876 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070015877 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015878 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
15879 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070015880 {
15881 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
15882 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015884 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015885 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
15886 if (status != VOS_STATUS_SUCCESS) {
15887 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
15888 }
Hoonki Lee14621352013-04-16 17:51:19 -070015889 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015890 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015891 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015892 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
15893 }
15894 }
Hoonki Lee14621352013-04-16 17:51:19 -070015895 }
15896
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015897 /* make sure doesn't call send_mgmt() while it is pending */
15898 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
15899 {
15900 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015901 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015902 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015903 ret = -EBUSY;
15904 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015905 }
15906
15907 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015908 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
15909
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015910 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
15911 pAdapter->sessionId, peer, action_code, dialog_token,
15912 status_code, peer_capability, (tANI_U8 *)buf, len,
15913 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015914
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015915 if (VOS_STATUS_SUCCESS != status)
15916 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015917 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15918 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015919 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015920 ret = -EINVAL;
15921 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015922 }
15923
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015924 if ((SIR_MAC_TDLS_DIS_REQ == action_code) ||
15925 (SIR_MAC_TDLS_DIS_RSP == action_code))
15926 {
15927 /* for DIS_REQ/DIS_RSP, supplicant don't consider the return status.
15928 * So we no need to wait for tdls_mgmt_comp for sending ack status.
15929 */
15930 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15931 "%s: tx done for frm %u", __func__, action_code);
15932 return 0;
15933 }
15934
15935 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15936 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
15937 WAIT_TIME_TDLS_MGMT);
15938
Hoonki Leed37cbb32013-04-20 00:31:14 -070015939 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
15940 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
15941
15942 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015943 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070015944 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015945 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070015946 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015947 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080015948
15949 if (pHddCtx->isLogpInProgress)
15950 {
15951 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15952 "%s: LOGP in Progress. Ignore!!!", __func__);
15953 return -EAGAIN;
15954 }
15955
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015956 ret = -EINVAL;
15957 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015958 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015959 else
15960 {
15961 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15962 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
15963 __func__, rc, pAdapter->mgmtTxCompletionStatus);
15964 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015965
Gopichand Nakkala05922802013-03-14 12:23:19 -070015966 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070015967 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015968 ret = max_sta_failed;
15969 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070015970 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015971
Hoonki Leea34dd892013-02-05 22:56:02 -080015972 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
15973 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015974 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015975 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15976 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015977 }
15978 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
15979 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015980 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015981 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15982 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015983 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015984
15985 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015986
15987tx_failed:
15988 /* add_station will be called before sending TDLS_SETUP_REQ and
15989 * TDLS_SETUP_RSP and as part of add_station driver will enable
15990 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
15991 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
15992 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
15993 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
15994 */
15995
15996 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
15997 (SIR_MAC_TDLS_SETUP_RSP == action_code))
15998 wlan_hdd_tdls_check_bmps(pAdapter);
15999 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016000}
16001
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016002#if TDLS_MGMT_VERSION2
16003static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
16004 u8 *peer, u8 action_code, u8 dialog_token,
16005 u16 status_code, u32 peer_capability,
16006 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016007#else /* TDLS_MGMT_VERSION2 */
16008#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
16009static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16010 struct net_device *dev,
16011 const u8 *peer, u8 action_code,
16012 u8 dialog_token, u16 status_code,
16013 u32 peer_capability, bool initiator,
16014 const u8 *buf, size_t len)
16015#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16016static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16017 struct net_device *dev,
16018 const u8 *peer, u8 action_code,
16019 u8 dialog_token, u16 status_code,
16020 u32 peer_capability, const u8 *buf,
16021 size_t len)
16022#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
16023static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
16024 struct net_device *dev,
16025 u8 *peer, u8 action_code,
16026 u8 dialog_token,
16027 u16 status_code, u32 peer_capability,
16028 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016029#else
16030static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
16031 u8 *peer, u8 action_code, u8 dialog_token,
16032 u16 status_code, const u8 *buf, size_t len)
16033#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016034#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016035{
16036 int ret;
16037
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016038 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016039#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016040 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16041 dialog_token, status_code,
16042 peer_capability, buf, len);
16043#else /* TDLS_MGMT_VERSION2 */
16044#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
16045 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16046 dialog_token, status_code,
16047 peer_capability, initiator,
16048 buf, len);
16049#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
16050 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16051 dialog_token, status_code,
16052 peer_capability, buf, len);
16053#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
16054 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16055 dialog_token, status_code,
16056 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016057#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016058 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
16059 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016060#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016061#endif
16062 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016063
Anand N Sunkad9f80b742015-07-30 20:05:51 +053016064 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016065}
Atul Mittal115287b2014-07-08 13:26:33 +053016066
16067int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016068#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16069 const u8 *peer,
16070#else
Atul Mittal115287b2014-07-08 13:26:33 +053016071 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016072#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016073 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053016074 cfg80211_exttdls_callback callback)
16075{
16076
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016077 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053016078 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016079 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053016080 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16081 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
16082 __func__, MAC_ADDR_ARRAY(peer));
16083
16084 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
16085 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
16086
16087 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016088 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
16089 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
16090 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053016091 return -ENOTSUPP;
16092 }
16093
16094 /* To cater the requirement of establishing the TDLS link
16095 * irrespective of the data traffic , get an entry of TDLS peer.
16096 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053016097 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053016098 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
16099 if (pTdlsPeer == NULL) {
16100 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16101 "%s: peer " MAC_ADDRESS_STR " not existing",
16102 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053016103 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053016104 return -EINVAL;
16105 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053016106 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053016107
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053016108 /* check FW TDLS Off Channel capability */
16109 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053016110 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053016111 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016112 {
16113 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
16114 pTdlsPeer->peerParams.global_operating_class =
16115 tdls_peer_params->global_operating_class;
16116 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
16117 pTdlsPeer->peerParams.min_bandwidth_kbps =
16118 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016119 /* check configured channel is valid, non dfs and
16120 * not current operating channel */
16121 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
16122 tdls_peer_params->channel)) &&
16123 (pHddStaCtx) &&
16124 (tdls_peer_params->channel !=
16125 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016126 {
16127 pTdlsPeer->isOffChannelConfigured = TRUE;
16128 }
16129 else
16130 {
16131 pTdlsPeer->isOffChannelConfigured = FALSE;
16132 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16133 "%s: Configured Tdls Off Channel is not valid", __func__);
16134
16135 }
16136 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016137 "%s: tdls_off_channel %d isOffChannelConfigured %d "
16138 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016139 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053016140 pTdlsPeer->isOffChannelConfigured,
16141 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016142 }
16143 else
16144 {
16145 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053016146 "%s: TDLS off channel FW capability %d, "
16147 "host capab %d or Invalid TDLS Peer Params", __func__,
16148 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
16149 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016150 }
16151
Atul Mittal115287b2014-07-08 13:26:33 +053016152 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
16153
16154 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16155 " %s TDLS Add Force Peer Failed",
16156 __func__);
16157 return -EINVAL;
16158 }
16159 /*EXT TDLS*/
16160
16161 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
16162 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16163 " %s TDLS set callback Failed",
16164 __func__);
16165 return -EINVAL;
16166 }
16167
16168 return(0);
16169
16170}
16171
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016172int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
16173#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16174 const u8 *peer
16175#else
16176 u8 *peer
16177#endif
16178)
Atul Mittal115287b2014-07-08 13:26:33 +053016179{
16180
16181 hddTdlsPeer_t *pTdlsPeer;
16182 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16183 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16184 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
16185 __func__, MAC_ADDR_ARRAY(peer));
16186
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016187 if (0 != wlan_hdd_validate_context(pHddCtx)) {
16188 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
16189 return -EINVAL;
16190 }
16191
Atul Mittal115287b2014-07-08 13:26:33 +053016192 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
16193 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
16194
16195 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016196 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
16197 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
16198 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053016199 return -ENOTSUPP;
16200 }
16201
16202
16203 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
16204
16205 if ( NULL == pTdlsPeer ) {
16206 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016207 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053016208 __func__, MAC_ADDR_ARRAY(peer));
16209 return -EINVAL;
16210 }
16211 else {
16212 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
16213 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016214 /* if channel switch is configured, reset
16215 the channel for this peer */
16216 if (TRUE == pTdlsPeer->isOffChannelConfigured)
16217 {
16218 pTdlsPeer->peerParams.channel = 0;
16219 pTdlsPeer->isOffChannelConfigured = FALSE;
16220 }
Atul Mittal115287b2014-07-08 13:26:33 +053016221 }
16222
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016223 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
16224 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053016225 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016226 }
Atul Mittal115287b2014-07-08 13:26:33 +053016227
16228 /*EXT TDLS*/
16229
16230 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
16231
16232 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16233 " %s TDLS set callback Failed",
16234 __func__);
16235 return -EINVAL;
16236 }
16237 return(0);
16238
16239}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016240static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016241#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16242 const u8 *peer,
16243#else
16244 u8 *peer,
16245#endif
16246 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016247{
16248 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16249 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016250 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016251 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016252
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016253 ENTER();
16254
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016255 if (!pAdapter) {
16256 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
16257 return -EINVAL;
16258 }
16259
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016260 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16261 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
16262 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016263 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016264 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016265 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070016266 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016267 return -EINVAL;
16268 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016269
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016270 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016271 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080016272 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016273 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080016274 }
16275
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016276
16277 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016278 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016279 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016281 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
16282 "Cannot process TDLS commands",
16283 pHddCtx->cfg_ini->fEnableTDLSSupport,
16284 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016285 return -ENOTSUPP;
16286 }
16287
16288 switch (oper) {
16289 case NL80211_TDLS_ENABLE_LINK:
16290 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016291 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016292 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016293 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053016294 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016295 tANI_U16 numCurrTdlsPeers = 0;
16296 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016297 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016298
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016299 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16300 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
16301 __func__, MAC_ADDR_ARRAY(peer));
Sunil Dutt41de4e22013-11-14 18:09:02 +053016302 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053016303 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053016304 if ( NULL == pTdlsPeer ) {
16305 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
16306 " (oper %d) not exsting. ignored",
16307 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
16308 return -EINVAL;
16309 }
16310
16311 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16312 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
16313 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
16314 "NL80211_TDLS_ENABLE_LINK");
16315
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070016316 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
16317 {
16318 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
16319 MAC_ADDRESS_STR " failed",
16320 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
16321 return -EINVAL;
16322 }
16323
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053016324 /* before starting tdls connection, set tdls
16325 * off channel established status to default value */
16326 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016327 /* TDLS Off Channel, Disable tdls channel switch,
16328 when there are more than one tdls link */
16329 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053016330 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016331 {
16332 /* get connected peer and send disable tdls off chan */
16333 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016334 if ((connPeer) &&
16335 (connPeer->isOffChannelSupported == TRUE) &&
16336 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016337 {
16338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16339 "%s: More then one peer connected, Disable "
16340 "TDLS channel switch", __func__);
16341
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016342 connPeer->isOffChannelEstablished = FALSE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016343 ret = sme_SendTdlsChanSwitchReq(
16344 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016345 pAdapter->sessionId,
16346 connPeer->peerMac,
16347 connPeer->peerParams.channel,
16348 TDLS_OFF_CHANNEL_BW_OFFSET,
16349 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016350 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016351 hddLog(VOS_TRACE_LEVEL_ERROR,
16352 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016353 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016354 }
16355 else
16356 {
16357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16358 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016359 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016360 "isOffChannelConfigured %d",
16361 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016362 (connPeer ? (connPeer->isOffChannelSupported)
16363 : -1),
16364 (connPeer ? (connPeer->isOffChannelConfigured)
16365 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016366 }
16367 }
16368
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016369 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016370 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016371 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053016372
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016373 if (0 != wlan_hdd_tdls_get_link_establish_params(
16374 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016375 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016376 return -EINVAL;
16377 }
16378 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016379
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016380 ret = sme_SendTdlsLinkEstablishParams(
16381 WLAN_HDD_GET_HAL_CTX(pAdapter),
16382 pAdapter->sessionId, peer,
16383 &tdlsLinkEstablishParams);
16384 if (ret != VOS_STATUS_SUCCESS) {
16385 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
16386 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016387 /* Send TDLS peer UAPSD capabilities to the firmware and
16388 * register with the TL on after the response for this operation
16389 * is received .
16390 */
16391 ret = wait_for_completion_interruptible_timeout(
16392 &pAdapter->tdls_link_establish_req_comp,
16393 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
16394 if (ret <= 0)
16395 {
16396 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016397 FL("Link Establish Request Failed Status %ld"),
16398 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016399 return -EINVAL;
16400 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016401 }
Atul Mittal115287b2014-07-08 13:26:33 +053016402 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
16403 eTDLS_LINK_CONNECTED,
16404 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053016405 staDesc.ucSTAId = pTdlsPeer->staId;
16406 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016407 ret = WLANTL_UpdateTdlsSTAClient(
16408 pHddCtx->pvosContext,
16409 &staDesc);
16410 if (ret != VOS_STATUS_SUCCESS) {
16411 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
16412 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053016413
Gopichand Nakkala471708b2013-06-04 20:03:01 +053016414 /* Mark TDLS client Authenticated .*/
16415 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
16416 pTdlsPeer->staId,
16417 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070016418 if (VOS_STATUS_SUCCESS == status)
16419 {
Hoonki Lee14621352013-04-16 17:51:19 -070016420 if (pTdlsPeer->is_responder == 0)
16421 {
16422 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
16423
16424 wlan_hdd_tdls_timer_restart(pAdapter,
16425 &pTdlsPeer->initiatorWaitTimeoutTimer,
16426 WAIT_TIME_TDLS_INITIATOR);
16427 /* suspend initiator TX until it receives direct packet from the
16428 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016429 ret = WLANTL_SuspendDataTx(
16430 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
16431 &staId, NULL);
16432 if (ret != VOS_STATUS_SUCCESS) {
16433 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
16434 }
Hoonki Lee14621352013-04-16 17:51:19 -070016435 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016436
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016437 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016438 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016439 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016440 suppChannelLen =
16441 tdlsLinkEstablishParams.supportedChannelsLen;
16442
16443 if ((suppChannelLen > 0) &&
16444 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
16445 {
16446 tANI_U8 suppPeerChannel = 0;
16447 int i = 0;
16448 for (i = 0U; i < suppChannelLen; i++)
16449 {
16450 suppPeerChannel =
16451 tdlsLinkEstablishParams.supportedChannels[i];
16452
16453 pTdlsPeer->isOffChannelSupported = FALSE;
16454 if (suppPeerChannel ==
16455 pTdlsPeer->peerParams.channel)
16456 {
16457 pTdlsPeer->isOffChannelSupported = TRUE;
16458 break;
16459 }
16460 }
16461 }
16462 else
16463 {
16464 pTdlsPeer->isOffChannelSupported = FALSE;
16465 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016466 }
16467 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16468 "%s: TDLS channel switch request for channel "
16469 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016470 "%d isOffChannelSupported %d", __func__,
16471 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016472 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016473 suppChannelLen,
16474 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016475
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016476 /* TDLS Off Channel, Enable tdls channel switch,
16477 when their is only one tdls link and it supports */
16478 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
16479 if ((numCurrTdlsPeers == 1) &&
16480 (TRUE == pTdlsPeer->isOffChannelSupported) &&
16481 (TRUE == pTdlsPeer->isOffChannelConfigured))
16482 {
16483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16484 "%s: Send TDLS channel switch request for channel %d",
16485 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016486
16487 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016488 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
16489 pAdapter->sessionId,
16490 pTdlsPeer->peerMac,
16491 pTdlsPeer->peerParams.channel,
16492 TDLS_OFF_CHANNEL_BW_OFFSET,
16493 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016494 if (ret != VOS_STATUS_SUCCESS) {
16495 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
16496 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016497 }
16498 else
16499 {
16500 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16501 "%s: TDLS channel switch request not sent"
16502 " numCurrTdlsPeers %d "
16503 "isOffChannelSupported %d "
16504 "isOffChannelConfigured %d",
16505 __func__, numCurrTdlsPeers,
16506 pTdlsPeer->isOffChannelSupported,
16507 pTdlsPeer->isOffChannelConfigured);
16508 }
16509
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070016510 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016511 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016512
16513 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016514 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
16515 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016516 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016517 int ac;
16518 uint8 ucAc[4] = { WLANTL_AC_VO,
16519 WLANTL_AC_VI,
16520 WLANTL_AC_BK,
16521 WLANTL_AC_BE };
16522 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
16523 for(ac=0; ac < 4; ac++)
16524 {
16525 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
16526 pTdlsPeer->staId, ucAc[ac],
16527 tlTid[ac], tlTid[ac], 0, 0,
16528 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016529 if (status != VOS_STATUS_SUCCESS) {
16530 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
16531 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016532 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016533 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016534 }
16535
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016536 }
16537 break;
16538 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080016539 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016540 tANI_U16 numCurrTdlsPeers = 0;
16541 hddTdlsPeer_t *connPeer = NULL;
16542
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16544 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
16545 __func__, MAC_ADDR_ARRAY(peer));
16546
Sunil Dutt41de4e22013-11-14 18:09:02 +053016547 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
16548
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016549
Sunil Dutt41de4e22013-11-14 18:09:02 +053016550 if ( NULL == pTdlsPeer ) {
16551 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
16552 " (oper %d) not exsting. ignored",
16553 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
16554 return -EINVAL;
16555 }
16556
16557 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16558 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
16559 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
16560 "NL80211_TDLS_DISABLE_LINK");
16561
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016562 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080016563 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016564 long status;
16565
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053016566 /* set tdls off channel status to false for this peer */
16567 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053016568 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
16569 eTDLS_LINK_TEARING,
16570 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
16571 eTDLS_LINK_UNSPECIFIED:
16572 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016573 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
16574
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016575 status = sme_DeleteTdlsPeerSta(
16576 WLAN_HDD_GET_HAL_CTX(pAdapter),
16577 pAdapter->sessionId, peer );
16578 if (status != VOS_STATUS_SUCCESS) {
16579 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
16580 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016581
16582 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
16583 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053016584 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053016585 eTDLS_LINK_IDLE,
16586 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016587 if (status <= 0)
16588 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016589 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16590 "%s: Del station failed status %ld",
16591 __func__, status);
16592 return -EPERM;
16593 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016594
16595 /* TDLS Off Channel, Enable tdls channel switch,
16596 when their is only one tdls link and it supports */
16597 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
16598 if (numCurrTdlsPeers == 1)
16599 {
16600 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
16601 if ((connPeer) &&
16602 (connPeer->isOffChannelSupported == TRUE) &&
16603 (connPeer->isOffChannelConfigured == TRUE))
16604 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016605 connPeer->isOffChannelEstablished = TRUE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016606 status = sme_SendTdlsChanSwitchReq(
16607 WLAN_HDD_GET_HAL_CTX(pAdapter),
16608 pAdapter->sessionId,
16609 connPeer->peerMac,
16610 connPeer->peerParams.channel,
16611 TDLS_OFF_CHANNEL_BW_OFFSET,
16612 TDLS_CHANNEL_SWITCH_ENABLE);
16613 if (status != VOS_STATUS_SUCCESS) {
16614 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
16615 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016616 }
16617 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16618 "%s: TDLS channel switch "
16619 "isOffChannelSupported %d "
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016620 "isOffChannelConfigured %d "
16621 "isOffChannelEstablished %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016622 __func__,
16623 (connPeer ? connPeer->isOffChannelSupported : -1),
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016624 (connPeer ? connPeer->isOffChannelConfigured : -1),
16625 (connPeer ? connPeer->isOffChannelEstablished : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016626 }
16627 else
16628 {
16629 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16630 "%s: TDLS channel switch request not sent "
16631 "numCurrTdlsPeers %d ",
16632 __func__, numCurrTdlsPeers);
16633 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080016634 }
16635 else
16636 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016637 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16638 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080016639 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080016640 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016641 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016642 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053016643 {
Atul Mittal115287b2014-07-08 13:26:33 +053016644 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053016645
Atul Mittal115287b2014-07-08 13:26:33 +053016646 if (0 != status)
16647 {
16648 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016649 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053016650 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053016651 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053016652 break;
16653 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016654 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053016655 {
Atul Mittal115287b2014-07-08 13:26:33 +053016656 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
16657 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016658 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053016659 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053016660
Atul Mittal115287b2014-07-08 13:26:33 +053016661 if (0 != status)
16662 {
16663 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016664 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053016665 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053016666 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053016667 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053016668 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016669 case NL80211_TDLS_DISCOVERY_REQ:
16670 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016671 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016672 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016673 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016674 return -ENOTSUPP;
16675 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016676 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16677 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016678 return -ENOTSUPP;
16679 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016680
16681 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016682 return 0;
16683}
Chilam NG571c65a2013-01-19 12:27:36 +053016684
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016685static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016686#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16687 const u8 *peer,
16688#else
16689 u8 *peer,
16690#endif
16691 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016692{
16693 int ret;
16694
16695 vos_ssr_protect(__func__);
16696 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
16697 vos_ssr_unprotect(__func__);
16698
16699 return ret;
16700}
16701
Chilam NG571c65a2013-01-19 12:27:36 +053016702int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
16703 struct net_device *dev, u8 *peer)
16704{
Arif Hussaina7c8e412013-11-20 11:06:42 -080016705 hddLog(VOS_TRACE_LEVEL_INFO,
16706 "tdls send discover req: "MAC_ADDRESS_STR,
16707 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053016708
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016709#if TDLS_MGMT_VERSION2
16710 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16711 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16712#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016713#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
16714 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16715 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
16716#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16717 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16718 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16719#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
16720 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16721 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16722#else
Chilam NG571c65a2013-01-19 12:27:36 +053016723 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16724 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016725#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016726#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053016727}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016728#endif
16729
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016730#ifdef WLAN_FEATURE_GTK_OFFLOAD
16731/*
16732 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
16733 * Callback rountine called upon receiving response for
16734 * get offload info
16735 */
16736void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
16737 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
16738{
16739
16740 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016741 tANI_U8 tempReplayCounter[8];
16742 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016743
16744 ENTER();
16745
16746 if (NULL == pAdapter)
16747 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016748 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016749 "%s: HDD adapter is Null", __func__);
16750 return ;
16751 }
16752
16753 if (NULL == pGtkOffloadGetInfoRsp)
16754 {
16755 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16756 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
16757 return ;
16758 }
16759
16760 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
16761 {
16762 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16763 "%s: wlan Failed to get replay counter value",
16764 __func__);
16765 return ;
16766 }
16767
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016768 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16769 /* Update replay counter */
16770 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
16771 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16772
16773 {
16774 /* changing from little to big endian since supplicant
16775 * works on big endian format
16776 */
16777 int i;
16778 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16779
16780 for (i = 0; i < 8; i++)
16781 {
16782 tempReplayCounter[7-i] = (tANI_U8)p[i];
16783 }
16784 }
16785
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016786 /* Update replay counter to NL */
16787 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016788 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016789}
16790
16791/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016792 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016793 * This function is used to offload GTK rekeying job to the firmware.
16794 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016795int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016796 struct cfg80211_gtk_rekey_data *data)
16797{
16798 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16799 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16800 hdd_station_ctx_t *pHddStaCtx;
16801 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016802 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016803 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016804 eHalStatus status = eHAL_STATUS_FAILURE;
16805
16806 ENTER();
16807
16808 if (NULL == pAdapter)
16809 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016810 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016811 "%s: HDD adapter is Null", __func__);
16812 return -ENODEV;
16813 }
16814
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016815 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16816 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
16817 pAdapter->sessionId, pAdapter->device_mode));
16818
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016819 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016820 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016821 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016822 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016823 }
16824
16825 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16826 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16827 if (NULL == hHal)
16828 {
16829 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16830 "%s: HAL context is Null!!!", __func__);
16831 return -EAGAIN;
16832 }
16833
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016834 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
16835 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
16836 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
16837 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016838 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016839 {
16840 /* changing from big to little endian since driver
16841 * works on little endian format
16842 */
16843 tANI_U8 *p =
16844 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
16845 int i;
16846
16847 for (i = 0; i < 8; i++)
16848 {
16849 p[7-i] = data->replay_ctr[i];
16850 }
16851 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016852
16853 if (TRUE == pHddCtx->hdd_wlan_suspended)
16854 {
16855 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016856 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
16857 sizeof (tSirGtkOffloadParams));
16858 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016859 pAdapter->sessionId);
16860
16861 if (eHAL_STATUS_SUCCESS != status)
16862 {
16863 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16864 "%s: sme_SetGTKOffload failed, returned %d",
16865 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016866
16867 /* Need to clear any trace of key value in the memory.
16868 * Thus zero out the memory even though it is local
16869 * variable.
16870 */
16871 vos_mem_zero(&hddGtkOffloadReqParams,
16872 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016873 return status;
16874 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016875 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16876 "%s: sme_SetGTKOffload successfull", __func__);
16877 }
16878 else
16879 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016880 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16881 "%s: wlan not suspended GTKOffload request is stored",
16882 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016883 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016884
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016885 /* Need to clear any trace of key value in the memory.
16886 * Thus zero out the memory even though it is local
16887 * variable.
16888 */
16889 vos_mem_zero(&hddGtkOffloadReqParams,
16890 sizeof(hddGtkOffloadReqParams));
16891
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016892 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016893 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016894}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016895
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016896int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
16897 struct cfg80211_gtk_rekey_data *data)
16898{
16899 int ret;
16900
16901 vos_ssr_protect(__func__);
16902 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
16903 vos_ssr_unprotect(__func__);
16904
16905 return ret;
16906}
16907#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016908/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016909 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016910 * This function is used to set access control policy
16911 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016912static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
16913 struct net_device *dev,
16914 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016915{
16916 int i;
16917 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16918 hdd_hostapd_state_t *pHostapdState;
16919 tsap_Config_t *pConfig;
16920 v_CONTEXT_t pVosContext = NULL;
16921 hdd_context_t *pHddCtx;
16922 int status;
16923
16924 ENTER();
16925
16926 if (NULL == pAdapter)
16927 {
16928 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16929 "%s: HDD adapter is Null", __func__);
16930 return -ENODEV;
16931 }
16932
16933 if (NULL == params)
16934 {
16935 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16936 "%s: params is Null", __func__);
16937 return -EINVAL;
16938 }
16939
16940 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16941 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016942 if (0 != status)
16943 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016944 return status;
16945 }
16946
16947 pVosContext = pHddCtx->pvosContext;
16948 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
16949
16950 if (NULL == pHostapdState)
16951 {
16952 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16953 "%s: pHostapdState is Null", __func__);
16954 return -EINVAL;
16955 }
16956
16957 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
16958 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016959 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16960 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
16961 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016962
16963 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
16964 {
16965 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
16966
16967 /* default value */
16968 pConfig->num_accept_mac = 0;
16969 pConfig->num_deny_mac = 0;
16970
16971 /**
16972 * access control policy
16973 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
16974 * listed in hostapd.deny file.
16975 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
16976 * listed in hostapd.accept file.
16977 */
16978 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
16979 {
16980 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
16981 }
16982 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
16983 {
16984 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
16985 }
16986 else
16987 {
16988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16989 "%s:Acl Policy : %d is not supported",
16990 __func__, params->acl_policy);
16991 return -ENOTSUPP;
16992 }
16993
16994 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
16995 {
16996 pConfig->num_accept_mac = params->n_acl_entries;
16997 for (i = 0; i < params->n_acl_entries; i++)
16998 {
16999 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17000 "** Add ACL MAC entry %i in WhiletList :"
17001 MAC_ADDRESS_STR, i,
17002 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
17003
17004 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
17005 sizeof(qcmacaddr));
17006 }
17007 }
17008 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
17009 {
17010 pConfig->num_deny_mac = params->n_acl_entries;
17011 for (i = 0; i < params->n_acl_entries; i++)
17012 {
17013 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17014 "** Add ACL MAC entry %i in BlackList :"
17015 MAC_ADDRESS_STR, i,
17016 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
17017
17018 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
17019 sizeof(qcmacaddr));
17020 }
17021 }
17022
17023 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
17024 {
17025 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17026 "%s: SAP Set Mac Acl fail", __func__);
17027 return -EINVAL;
17028 }
17029 }
17030 else
17031 {
17032 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053017033 "%s: Invalid device_mode = %s (%d)",
17034 __func__, hdd_device_modetoString(pAdapter->device_mode),
17035 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017036 return -EINVAL;
17037 }
17038
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017039 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017040 return 0;
17041}
17042
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053017043static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
17044 struct net_device *dev,
17045 const struct cfg80211_acl_data *params)
17046{
17047 int ret;
17048 vos_ssr_protect(__func__);
17049 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
17050 vos_ssr_unprotect(__func__);
17051
17052 return ret;
17053}
17054
Leo Chang9056f462013-08-01 19:21:11 -070017055#ifdef WLAN_NL80211_TESTMODE
17056#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070017057void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070017058(
17059 void *pAdapter,
17060 void *indCont
17061)
17062{
Leo Changd9df8aa2013-09-26 13:32:26 -070017063 tSirLPHBInd *lphbInd;
17064 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053017065 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070017066
17067 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070017068 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070017069
c_hpothu73f35e62014-04-18 13:40:08 +053017070 if (pAdapter == NULL)
17071 {
17072 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17073 "%s: pAdapter is NULL\n",__func__);
17074 return;
17075 }
17076
Leo Chang9056f462013-08-01 19:21:11 -070017077 if (NULL == indCont)
17078 {
17079 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070017080 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070017081 return;
17082 }
17083
c_hpothu73f35e62014-04-18 13:40:08 +053017084 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070017085 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070017086 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053017087 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070017088 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070017089 GFP_ATOMIC);
17090 if (!skb)
17091 {
17092 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17093 "LPHB timeout, NL buffer alloc fail");
17094 return;
17095 }
17096
Leo Changac3ba772013-10-07 09:47:04 -070017097 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070017098 {
17099 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17100 "WLAN_HDD_TM_ATTR_CMD put fail");
17101 goto nla_put_failure;
17102 }
Leo Changac3ba772013-10-07 09:47:04 -070017103 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070017104 {
17105 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17106 "WLAN_HDD_TM_ATTR_TYPE put fail");
17107 goto nla_put_failure;
17108 }
Leo Changac3ba772013-10-07 09:47:04 -070017109 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070017110 sizeof(tSirLPHBInd), lphbInd))
17111 {
17112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17113 "WLAN_HDD_TM_ATTR_DATA put fail");
17114 goto nla_put_failure;
17115 }
Leo Chang9056f462013-08-01 19:21:11 -070017116 cfg80211_testmode_event(skb, GFP_ATOMIC);
17117 return;
17118
17119nla_put_failure:
17120 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17121 "NLA Put fail");
17122 kfree_skb(skb);
17123
17124 return;
17125}
17126#endif /* FEATURE_WLAN_LPHB */
17127
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017128static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070017129{
17130 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
17131 int err = 0;
17132#ifdef FEATURE_WLAN_LPHB
17133 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070017134 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017135
17136 ENTER();
17137
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017138 err = wlan_hdd_validate_context(pHddCtx);
17139 if (0 != err)
17140 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017141 return err;
17142 }
Leo Chang9056f462013-08-01 19:21:11 -070017143#endif /* FEATURE_WLAN_LPHB */
17144
17145 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
17146 if (err)
17147 {
17148 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17149 "%s Testmode INV ATTR", __func__);
17150 return err;
17151 }
17152
17153 if (!tb[WLAN_HDD_TM_ATTR_CMD])
17154 {
17155 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17156 "%s Testmode INV CMD", __func__);
17157 return -EINVAL;
17158 }
17159
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017160 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17161 TRACE_CODE_HDD_CFG80211_TESTMODE,
17162 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070017163 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
17164 {
17165#ifdef FEATURE_WLAN_LPHB
17166 /* Low Power Heartbeat configuration request */
17167 case WLAN_HDD_TM_CMD_WLAN_HB:
17168 {
17169 int buf_len;
17170 void *buf;
17171 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080017172 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070017173
17174 if (!tb[WLAN_HDD_TM_ATTR_DATA])
17175 {
17176 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17177 "%s Testmode INV DATA", __func__);
17178 return -EINVAL;
17179 }
17180
17181 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
17182 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080017183
17184 hb_params_temp =(tSirLPHBReq *)buf;
17185 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
17186 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
17187 return -EINVAL;
17188
Leo Chang9056f462013-08-01 19:21:11 -070017189 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
17190 if (NULL == hb_params)
17191 {
17192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17193 "%s Request Buffer Alloc Fail", __func__);
17194 return -EINVAL;
17195 }
17196
17197 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070017198 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
17199 hb_params,
17200 wlan_hdd_cfg80211_lphb_ind_handler);
17201 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070017202 {
Leo Changd9df8aa2013-09-26 13:32:26 -070017203 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17204 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070017205 vos_mem_free(hb_params);
17206 }
Leo Chang9056f462013-08-01 19:21:11 -070017207 return 0;
17208 }
17209#endif /* FEATURE_WLAN_LPHB */
17210 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017211 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17212 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070017213 return -EOPNOTSUPP;
17214 }
17215
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017216 EXIT();
17217 return err;
Leo Chang9056f462013-08-01 19:21:11 -070017218}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017219
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053017220static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
17221#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
17222 struct wireless_dev *wdev,
17223#endif
17224 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017225{
17226 int ret;
17227
17228 vos_ssr_protect(__func__);
17229 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
17230 vos_ssr_unprotect(__func__);
17231
17232 return ret;
17233}
Leo Chang9056f462013-08-01 19:21:11 -070017234#endif /* CONFIG_NL80211_TESTMODE */
17235
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017236static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017237 struct net_device *dev,
17238 int idx, struct survey_info *survey)
17239{
17240 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17241 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053017242 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017243 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053017244 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017245 v_S7_t snr,rssi;
17246 int status, i, j, filled = 0;
17247
17248 ENTER();
17249
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017250 if (NULL == pAdapter)
17251 {
17252 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17253 "%s: HDD adapter is Null", __func__);
17254 return -ENODEV;
17255 }
17256
17257 if (NULL == wiphy)
17258 {
17259 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17260 "%s: wiphy is Null", __func__);
17261 return -ENODEV;
17262 }
17263
17264 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17265 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017266 if (0 != status)
17267 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017268 return status;
17269 }
17270
Mihir Sheted9072e02013-08-21 17:02:29 +053017271 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17272
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017273 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053017274 0 != pAdapter->survey_idx ||
17275 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017276 {
17277 /* The survey dump ops when implemented completely is expected to
17278 * return a survey of all channels and the ops is called by the
17279 * kernel with incremental values of the argument 'idx' till it
17280 * returns -ENONET. But we can only support the survey for the
17281 * operating channel for now. survey_idx is used to track
17282 * that the ops is called only once and then return -ENONET for
17283 * the next iteration
17284 */
17285 pAdapter->survey_idx = 0;
17286 return -ENONET;
17287 }
17288
Mukul Sharma9d5233b2015-06-11 20:28:20 +053017289 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
17290 {
17291 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17292 "%s: Roaming in progress, hence return ", __func__);
17293 return -ENONET;
17294 }
17295
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017296 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17297
17298 wlan_hdd_get_snr(pAdapter, &snr);
17299 wlan_hdd_get_rssi(pAdapter, &rssi);
17300
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017301 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17302 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
17303 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017304 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
17305 hdd_wlan_get_freq(channel, &freq);
17306
17307
17308 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
17309 {
17310 if (NULL == wiphy->bands[i])
17311 {
17312 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
17313 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
17314 continue;
17315 }
17316
17317 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
17318 {
17319 struct ieee80211_supported_band *band = wiphy->bands[i];
17320
17321 if (band->channels[j].center_freq == (v_U16_t)freq)
17322 {
17323 survey->channel = &band->channels[j];
17324 /* The Rx BDs contain SNR values in dB for the received frames
17325 * while the supplicant expects noise. So we calculate and
17326 * return the value of noise (dBm)
17327 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
17328 */
17329 survey->noise = rssi - snr;
17330 survey->filled = SURVEY_INFO_NOISE_DBM;
17331 filled = 1;
17332 }
17333 }
17334 }
17335
17336 if (filled)
17337 pAdapter->survey_idx = 1;
17338 else
17339 {
17340 pAdapter->survey_idx = 0;
17341 return -ENONET;
17342 }
17343
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017344 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017345 return 0;
17346}
17347
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017348static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
17349 struct net_device *dev,
17350 int idx, struct survey_info *survey)
17351{
17352 int ret;
17353
17354 vos_ssr_protect(__func__);
17355 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
17356 vos_ssr_unprotect(__func__);
17357
17358 return ret;
17359}
17360
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017361/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017362 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017363 * this is called when cfg80211 driver resume
17364 * driver updates latest sched_scan scan result(if any) to cfg80211 database
17365 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017366int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017367{
17368 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17369 hdd_adapter_t *pAdapter;
17370 hdd_adapter_list_node_t *pAdapterNode, *pNext;
17371 VOS_STATUS status = VOS_STATUS_SUCCESS;
17372
17373 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017374
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017375 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017376 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017377 return 0;
17378 }
17379
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017380 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
17381 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017382 spin_lock(&pHddCtx->schedScan_lock);
17383 pHddCtx->isWiphySuspended = FALSE;
17384 if (TRUE != pHddCtx->isSchedScanUpdatePending)
17385 {
17386 spin_unlock(&pHddCtx->schedScan_lock);
17387 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17388 "%s: Return resume is not due to PNO indication", __func__);
17389 return 0;
17390 }
17391 // Reset flag to avoid updatating cfg80211 data old results again
17392 pHddCtx->isSchedScanUpdatePending = FALSE;
17393 spin_unlock(&pHddCtx->schedScan_lock);
17394
17395 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
17396
17397 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
17398 {
17399 pAdapter = pAdapterNode->pAdapter;
17400 if ( (NULL != pAdapter) &&
17401 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
17402 {
17403 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017404 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017405 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
17406 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017407 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017408 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017409 {
17410 /* Acquire wakelock to handle the case where APP's tries to
17411 * suspend immediately after updating the scan results. Whis
17412 * results in app's is in suspended state and not able to
17413 * process the connect request to AP
17414 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053017415 hdd_prevent_suspend_timeout(2000,
17416 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017417 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017418 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017419
17420 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17421 "%s : cfg80211 scan result database updated", __func__);
17422
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017423 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017424 return 0;
17425
17426 }
17427 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
17428 pAdapterNode = pNext;
17429 }
17430
17431 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17432 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017433 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017434 return 0;
17435}
17436
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017437int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
17438{
17439 int ret;
17440
17441 vos_ssr_protect(__func__);
17442 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
17443 vos_ssr_unprotect(__func__);
17444
17445 return ret;
17446}
17447
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017448/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017449 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017450 * this is called when cfg80211 driver suspends
17451 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017452int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017453 struct cfg80211_wowlan *wow)
17454{
17455 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017456 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017457
17458 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017459
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017460 ret = wlan_hdd_validate_context(pHddCtx);
17461 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017462 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017463 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017464 }
17465
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017466
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017467 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17468 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
17469 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017470 pHddCtx->isWiphySuspended = TRUE;
17471
17472 EXIT();
17473
17474 return 0;
17475}
17476
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017477int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
17478 struct cfg80211_wowlan *wow)
17479{
17480 int ret;
17481
17482 vos_ssr_protect(__func__);
17483 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
17484 vos_ssr_unprotect(__func__);
17485
17486 return ret;
17487}
Jeff Johnson295189b2012-06-20 16:38:30 -070017488/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017489static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070017490{
17491 .add_virtual_intf = wlan_hdd_add_virtual_intf,
17492 .del_virtual_intf = wlan_hdd_del_virtual_intf,
17493 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
17494 .change_station = wlan_hdd_change_station,
17495#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
17496 .add_beacon = wlan_hdd_cfg80211_add_beacon,
17497 .del_beacon = wlan_hdd_cfg80211_del_beacon,
17498 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017499#else
17500 .start_ap = wlan_hdd_cfg80211_start_ap,
17501 .change_beacon = wlan_hdd_cfg80211_change_beacon,
17502 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070017503#endif
17504 .change_bss = wlan_hdd_cfg80211_change_bss,
17505 .add_key = wlan_hdd_cfg80211_add_key,
17506 .get_key = wlan_hdd_cfg80211_get_key,
17507 .del_key = wlan_hdd_cfg80211_del_key,
17508 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080017509#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070017510 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080017511#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017512 .scan = wlan_hdd_cfg80211_scan,
17513 .connect = wlan_hdd_cfg80211_connect,
17514 .disconnect = wlan_hdd_cfg80211_disconnect,
17515 .join_ibss = wlan_hdd_cfg80211_join_ibss,
17516 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
17517 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
17518 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
17519 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070017520 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
17521 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053017522 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070017523#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17524 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
17525 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
17526 .set_txq_params = wlan_hdd_set_txq_params,
17527#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017528 .get_station = wlan_hdd_cfg80211_get_station,
17529 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
17530 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017531 .add_station = wlan_hdd_cfg80211_add_station,
17532#ifdef FEATURE_WLAN_LFR
17533 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
17534 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
17535 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
17536#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017537#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
17538 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
17539#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017540#ifdef FEATURE_WLAN_TDLS
17541 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
17542 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
17543#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017544#ifdef WLAN_FEATURE_GTK_OFFLOAD
17545 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
17546#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017547#ifdef FEATURE_WLAN_SCAN_PNO
17548 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
17549 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
17550#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017551 .resume = wlan_hdd_cfg80211_resume_wlan,
17552 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017553 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070017554#ifdef WLAN_NL80211_TESTMODE
17555 .testmode_cmd = wlan_hdd_cfg80211_testmode,
17556#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017557 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070017558};
17559