blob: 9243f5627653879ccc5ebecf81d7859645d570a2 [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);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301230 tpSirWifiPeerStat pWifiPeerStat;
1231 tpSirWifiPeerInfo pWifiPeerInfo;
1232 struct nlattr *peerInfo;
1233 struct sk_buff *vendor_event;
1234 int status, i;
1235
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301236 ENTER();
1237
Sunil Duttc69bccb2014-05-26 21:30:20 +05301238 status = wlan_hdd_validate_context(pHddCtx);
1239 if (0 != status)
1240 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301241 return;
1242 }
1243
1244 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1245
1246 hddLog(VOS_TRACE_LEVEL_INFO,
1247 "LL_STATS_PEER_ALL : numPeers %u",
1248 pWifiPeerStat->numPeers);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301249 /*
1250 * Allocate a size of 4096 for the peer stats comprising
1251 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1252 * sizeof (tSirWifiRateStat).Each field is put with an
1253 * NL attribute.The size of 4096 is considered assuming
1254 * that number of rates shall not exceed beyond 50 with
1255 * the sizeof (tSirWifiRateStat) being 32.
1256 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301257 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1258 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301259 if (!vendor_event)
1260 {
1261 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301262 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301263 __func__);
1264 return;
1265 }
1266 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301267 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1268 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1269 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301270 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1271 pWifiPeerStat->numPeers))
1272 {
1273 hddLog(VOS_TRACE_LEVEL_ERROR,
1274 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1275 kfree_skb(vendor_event);
1276 return;
1277 }
1278
1279 peerInfo = nla_nest_start(vendor_event,
1280 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301281 if(!peerInfo)
1282 {
1283 hddLog(VOS_TRACE_LEVEL_ERROR,
1284 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1285 __func__);
1286 kfree_skb(vendor_event);
1287 return;
1288 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301289
1290 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1291 pWifiPeerStat->peerInfo);
1292
1293 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1294 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301295 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301296 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301297
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301298 if(!peers)
1299 {
1300 hddLog(VOS_TRACE_LEVEL_ERROR,
1301 "%s: peer stats put fail",
1302 __func__);
1303 kfree_skb(vendor_event);
1304 return;
1305 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301306 if (FALSE == put_wifi_peer_info(
1307 pWifiPeerInfo, vendor_event))
1308 {
1309 hddLog(VOS_TRACE_LEVEL_ERROR,
1310 "%s: put_wifi_peer_info put fail", __func__);
1311 kfree_skb(vendor_event);
1312 return;
1313 }
1314
1315 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1316 pWifiPeerStat->peerInfo +
1317 (i * sizeof(tSirWifiPeerInfo)) +
1318 (numRate * sizeof (tSirWifiRateStat)));
1319 nla_nest_end(vendor_event, peers);
1320 }
1321 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301322 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301323 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301324}
1325
1326/*
1327 * hdd_link_layer_process_iface_stats () - This function is called after
1328 * receiving Link Layer Interface statistics from FW.This function converts
1329 * the firmware data to the NL data and sends the same to the kernel/upper
1330 * layers.
1331 */
1332static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1333 v_VOID_t *pData)
1334{
1335 tpSirWifiIfaceStat pWifiIfaceStat;
1336 struct sk_buff *vendor_event;
1337 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1338 int status;
1339
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301340 ENTER();
1341
Sunil Duttc69bccb2014-05-26 21:30:20 +05301342 status = wlan_hdd_validate_context(pHddCtx);
1343 if (0 != status)
1344 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301345 return;
1346 }
1347 /*
1348 * Allocate a size of 4096 for the interface stats comprising
1349 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1350 * assuming that all these fit with in the limit.Please take
1351 * a call on the limit based on the data requirements on
1352 * interface statistics.
1353 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301354 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1355 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301356 if (!vendor_event)
1357 {
1358 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301359 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301360 return;
1361 }
1362
1363 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1364
Dino Mycle3b9536d2014-07-09 22:05:24 +05301365
1366 if (FALSE == hdd_get_interface_info( pAdapter,
1367 &pWifiIfaceStat->info))
1368 {
1369 hddLog(VOS_TRACE_LEVEL_ERROR,
1370 FL("hdd_get_interface_info get fail") );
1371 kfree_skb(vendor_event);
1372 return;
1373 }
1374
1375 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1376 vendor_event))
1377 {
1378 hddLog(VOS_TRACE_LEVEL_ERROR,
1379 FL("put_wifi_iface_stats fail") );
1380 kfree_skb(vendor_event);
1381 return;
1382 }
1383
Sunil Duttc69bccb2014-05-26 21:30:20 +05301384 hddLog(VOS_TRACE_LEVEL_INFO,
1385 "WMI_LINK_STATS_IFACE Data");
1386
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301387 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301388
1389 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301390}
1391
1392/*
1393 * hdd_link_layer_process_radio_stats () - This function is called after
1394 * receiving Link Layer Radio statistics from FW.This function converts
1395 * the firmware data to the NL data and sends the same to the kernel/upper
1396 * layers.
1397 */
1398static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1399 v_VOID_t *pData)
1400{
1401 int status, i;
1402 tpSirWifiRadioStat pWifiRadioStat;
1403 tpSirWifiChannelStats pWifiChannelStats;
1404 struct sk_buff *vendor_event;
1405 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1406 struct nlattr *chList;
1407
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301408 ENTER();
1409
Sunil Duttc69bccb2014-05-26 21:30:20 +05301410 status = wlan_hdd_validate_context(pHddCtx);
1411 if (0 != status)
1412 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301413 return;
1414 }
1415 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1416
1417 hddLog(VOS_TRACE_LEVEL_INFO,
1418 "LL_STATS_RADIO"
1419 " radio is %d onTime is %u "
1420 " txTime is %u rxTime is %u "
1421 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301422 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301423 " onTimePnoScan is %u onTimeHs20 is %u "
1424 " numChannels is %u",
1425 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1426 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1427 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301428 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301429 pWifiRadioStat->onTimeRoamScan,
1430 pWifiRadioStat->onTimePnoScan,
1431 pWifiRadioStat->onTimeHs20,
1432 pWifiRadioStat->numChannels);
1433 /*
1434 * Allocate a size of 4096 for the Radio stats comprising
1435 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1436 * (tSirWifiChannelStats).Each channel data is put with an
1437 * NL attribute.The size of 4096 is considered assuming that
1438 * number of channels shall not exceed beyond 60 with the
1439 * sizeof (tSirWifiChannelStats) being 24 bytes.
1440 */
1441
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301442 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1443 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301444 if (!vendor_event)
1445 {
1446 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301447 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301448 return;
1449 }
1450
1451 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301452 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1453 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1454 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301455 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1456 pWifiRadioStat->radio) ||
1457 nla_put_u32(vendor_event,
1458 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1459 pWifiRadioStat->onTime) ||
1460 nla_put_u32(vendor_event,
1461 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1462 pWifiRadioStat->txTime) ||
1463 nla_put_u32(vendor_event,
1464 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1465 pWifiRadioStat->rxTime) ||
1466 nla_put_u32(vendor_event,
1467 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1468 pWifiRadioStat->onTimeScan) ||
1469 nla_put_u32(vendor_event,
1470 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1471 pWifiRadioStat->onTimeNbd) ||
1472 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301473 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1474 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301475 nla_put_u32(vendor_event,
1476 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1477 pWifiRadioStat->onTimeRoamScan) ||
1478 nla_put_u32(vendor_event,
1479 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1480 pWifiRadioStat->onTimePnoScan) ||
1481 nla_put_u32(vendor_event,
1482 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1483 pWifiRadioStat->onTimeHs20) ||
1484 nla_put_u32(vendor_event,
1485 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1486 pWifiRadioStat->numChannels))
1487 {
1488 hddLog(VOS_TRACE_LEVEL_ERROR,
1489 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1490 kfree_skb(vendor_event);
1491 return ;
1492 }
1493
1494 chList = nla_nest_start(vendor_event,
1495 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301496 if(!chList)
1497 {
1498 hddLog(VOS_TRACE_LEVEL_ERROR,
1499 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1500 __func__);
1501 kfree_skb(vendor_event);
1502 return;
1503 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301504 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1505 {
1506 struct nlattr *chInfo;
1507
1508 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1509 pWifiRadioStat->channels +
1510 (i * sizeof(tSirWifiChannelStats)));
1511
Sunil Duttc69bccb2014-05-26 21:30:20 +05301512 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301513 if(!chInfo)
1514 {
1515 hddLog(VOS_TRACE_LEVEL_ERROR,
1516 "%s: failed to put chInfo",
1517 __func__);
1518 kfree_skb(vendor_event);
1519 return;
1520 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301521
1522 if (nla_put_u32(vendor_event,
1523 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1524 pWifiChannelStats->channel.width) ||
1525 nla_put_u32(vendor_event,
1526 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1527 pWifiChannelStats->channel.centerFreq) ||
1528 nla_put_u32(vendor_event,
1529 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1530 pWifiChannelStats->channel.centerFreq0) ||
1531 nla_put_u32(vendor_event,
1532 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1533 pWifiChannelStats->channel.centerFreq1) ||
1534 nla_put_u32(vendor_event,
1535 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1536 pWifiChannelStats->onTime) ||
1537 nla_put_u32(vendor_event,
1538 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1539 pWifiChannelStats->ccaBusyTime))
1540 {
1541 hddLog(VOS_TRACE_LEVEL_ERROR,
1542 FL("cfg80211_vendor_event_alloc failed") );
1543 kfree_skb(vendor_event);
1544 return ;
1545 }
1546 nla_nest_end(vendor_event, chInfo);
1547 }
1548 nla_nest_end(vendor_event, chList);
1549
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301550 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301551
1552 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301553 return;
1554}
1555
1556/*
1557 * hdd_link_layer_stats_ind_callback () - This function is called after
1558 * receiving Link Layer indications from FW.This callback converts the firmware
1559 * data to the NL data and send the same to the kernel/upper layers.
1560 */
1561static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1562 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301563 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301564{
Dino Mycled3d50022014-07-07 12:58:25 +05301565 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1566 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301567 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301568 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301569 int status;
1570
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301571 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301572
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301573 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301574 if (0 != status)
1575 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301576 return;
1577 }
1578
Dino Mycled3d50022014-07-07 12:58:25 +05301579 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1580 if (NULL == pAdapter)
1581 {
1582 hddLog(VOS_TRACE_LEVEL_ERROR,
1583 FL(" MAC address %pM does not exist with host"),
1584 macAddr);
1585 return;
1586 }
1587
Sunil Duttc69bccb2014-05-26 21:30:20 +05301588 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301589 "%s: Interface: %s LLStats indType: %d", __func__,
1590 pAdapter->dev->name, indType);
1591
Sunil Duttc69bccb2014-05-26 21:30:20 +05301592 switch (indType)
1593 {
1594 case SIR_HAL_LL_STATS_RESULTS_RSP:
1595 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301596 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301597 "LL_STATS RESP paramID = 0x%x, ifaceId = %u MAC: %pM "
1598 "respId = %u, moreResultToFollow = %u",
1599 linkLayerStatsResults->paramId, linkLayerStatsResults->ifaceId,
1600 macAddr, linkLayerStatsResults->respId,
1601 linkLayerStatsResults->moreResultToFollow);
1602
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301603 spin_lock(&hdd_context_lock);
1604 context = &pHddCtx->ll_stats_context;
1605 /* validate response received from target */
1606 if ((context->request_id != linkLayerStatsResults->respId) ||
1607 !(context->request_bitmap & linkLayerStatsResults->paramId))
1608 {
1609 spin_unlock(&hdd_context_lock);
1610 hddLog(LOGE,
1611 FL("Error : Request id %d response id %d request bitmap 0x%x"
1612 "response bitmap 0x%x"),
1613 context->request_id, linkLayerStatsResults->respId,
1614 context->request_bitmap, linkLayerStatsResults->paramId);
1615 return;
1616 }
1617 spin_unlock(&hdd_context_lock);
1618
Sunil Duttc69bccb2014-05-26 21:30:20 +05301619 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1620 {
1621 hdd_link_layer_process_radio_stats(pAdapter,
1622 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301623 spin_lock(&hdd_context_lock);
1624 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1625 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301626 }
1627 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1628 {
1629 hdd_link_layer_process_iface_stats(pAdapter,
1630 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301631 spin_lock(&hdd_context_lock);
1632 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1633 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301634 }
1635 else if ( linkLayerStatsResults->paramId &
1636 WMI_LINK_STATS_ALL_PEER )
1637 {
1638 hdd_link_layer_process_peer_stats(pAdapter,
1639 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301640 spin_lock(&hdd_context_lock);
1641 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1642 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301643 } /* WMI_LINK_STATS_ALL_PEER */
1644 else
1645 {
1646 hddLog(VOS_TRACE_LEVEL_ERROR,
1647 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1648 }
1649
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301650 spin_lock(&hdd_context_lock);
1651 /* complete response event if all requests are completed */
1652 if (0 == context->request_bitmap)
1653 complete(&context->response_event);
1654 spin_unlock(&hdd_context_lock);
1655
Sunil Duttc69bccb2014-05-26 21:30:20 +05301656 break;
1657 }
1658 default:
1659 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1660 break;
1661 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301662
1663 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301664 return;
1665}
1666
1667const struct
1668nla_policy
1669qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1670{
1671 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1672 { .type = NLA_U32 },
1673 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1674 { .type = NLA_U32 },
1675};
1676
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301677static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1678 struct wireless_dev *wdev,
1679 const void *data,
1680 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301681{
1682 int status;
1683 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301684 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301685 struct net_device *dev = wdev->netdev;
1686 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1687 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1688
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301689 ENTER();
1690
Sunil Duttc69bccb2014-05-26 21:30:20 +05301691 status = wlan_hdd_validate_context(pHddCtx);
1692 if (0 != status)
1693 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301694 return -EINVAL;
1695 }
1696
1697 if (NULL == pAdapter)
1698 {
1699 hddLog(VOS_TRACE_LEVEL_ERROR,
1700 FL("HDD adapter is Null"));
1701 return -ENODEV;
1702 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301703 /* check the LLStats Capability */
1704 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1705 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1706 {
1707 hddLog(VOS_TRACE_LEVEL_ERROR,
1708 FL("Link Layer Statistics not supported by Firmware"));
1709 return -EINVAL;
1710 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301711
1712 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1713 (struct nlattr *)data,
1714 data_len, qca_wlan_vendor_ll_set_policy))
1715 {
1716 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1717 return -EINVAL;
1718 }
1719 if (!tb_vendor
1720 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1721 {
1722 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1723 return -EINVAL;
1724 }
1725 if (!tb_vendor[
1726 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1727 {
1728 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1729 return -EINVAL;
1730 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301731 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301732 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301733
Dino Mycledf0a5d92014-07-04 09:41:55 +05301734 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301735 nla_get_u32(
1736 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1737
Dino Mycledf0a5d92014-07-04 09:41:55 +05301738 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301739 nla_get_u32(
1740 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1741
Dino Mycled3d50022014-07-07 12:58:25 +05301742 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1743 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301744
1745
1746 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301747 "LL_STATS_SET reqId = %d, MAC = %pM, mpduSizeThreshold = %d "
1748 "Statistics Gathering = %d ",
1749 linkLayerStatsSetReq.reqId, linkLayerStatsSetReq.macAddr,
1750 linkLayerStatsSetReq.mpduSizeThreshold,
1751 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301752
1753 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1754 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301755 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301756 {
1757 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1758 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301759 return -EINVAL;
1760
1761 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301762
Sunil Duttc69bccb2014-05-26 21:30:20 +05301763 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301764 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301765 {
1766 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1767 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301768 return -EINVAL;
1769 }
1770
1771 pAdapter->isLinkLayerStatsSet = 1;
1772
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301773 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301774 return 0;
1775}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301776static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1777 struct wireless_dev *wdev,
1778 const void *data,
1779 int data_len)
1780{
1781 int ret = 0;
1782
1783 vos_ssr_protect(__func__);
1784 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1785 vos_ssr_unprotect(__func__);
1786
1787 return ret;
1788}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301789
1790const struct
1791nla_policy
1792qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1793{
1794 /* Unsigned 32bit value provided by the caller issuing the GET stats
1795 * command. When reporting
1796 * the stats results, the driver uses the same value to indicate
1797 * which GET request the results
1798 * correspond to.
1799 */
1800 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1801
1802 /* Unsigned 32bit value . bit mask to identify what statistics are
1803 requested for retrieval */
1804 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1805};
1806
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301807static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1808 struct wireless_dev *wdev,
1809 const void *data,
1810 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301811{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301812 unsigned long rc;
1813 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301814 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1815 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301816 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301817 struct net_device *dev = wdev->netdev;
1818 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301819 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301820 int status;
1821
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301822 ENTER();
1823
Sunil Duttc69bccb2014-05-26 21:30:20 +05301824 status = wlan_hdd_validate_context(pHddCtx);
1825 if (0 != status)
1826 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301827 return -EINVAL ;
1828 }
1829
1830 if (NULL == pAdapter)
1831 {
1832 hddLog(VOS_TRACE_LEVEL_FATAL,
1833 "%s: HDD adapter is Null", __func__);
1834 return -ENODEV;
1835 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05301836
1837 if (pHddStaCtx == NULL)
1838 {
1839 hddLog(VOS_TRACE_LEVEL_FATAL,
1840 "%s: HddStaCtx is Null", __func__);
1841 return -ENODEV;
1842 }
1843
Dino Mycledf0a5d92014-07-04 09:41:55 +05301844 /* check the LLStats Capability */
1845 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1846 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1847 {
1848 hddLog(VOS_TRACE_LEVEL_ERROR,
1849 FL("Link Layer Statistics not supported by Firmware"));
1850 return -EINVAL;
1851 }
1852
Sunil Duttc69bccb2014-05-26 21:30:20 +05301853
1854 if (!pAdapter->isLinkLayerStatsSet)
1855 {
1856 hddLog(VOS_TRACE_LEVEL_FATAL,
1857 "%s: isLinkLayerStatsSet : %d",
1858 __func__, pAdapter->isLinkLayerStatsSet);
1859 return -EINVAL;
1860 }
1861
Mukul Sharma10313ba2015-07-29 19:14:39 +05301862 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
1863 {
1864 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
1865 "%s: Roaming in progress, so unable to proceed this request", __func__);
1866 return -EBUSY;
1867 }
1868
Sunil Duttc69bccb2014-05-26 21:30:20 +05301869 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
1870 (struct nlattr *)data,
1871 data_len, qca_wlan_vendor_ll_get_policy))
1872 {
1873 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1874 return -EINVAL;
1875 }
1876
1877 if (!tb_vendor
1878 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
1879 {
1880 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
1881 return -EINVAL;
1882 }
1883
1884 if (!tb_vendor
1885 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
1886 {
1887 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
1888 return -EINVAL;
1889 }
1890
Sunil Duttc69bccb2014-05-26 21:30:20 +05301891
Dino Mycledf0a5d92014-07-04 09:41:55 +05301892 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301893 nla_get_u32( tb_vendor[
1894 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05301895 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301896 nla_get_u32( tb_vendor[
1897 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
1898
Dino Mycled3d50022014-07-07 12:58:25 +05301899 vos_mem_copy(linkLayerStatsGetReq.macAddr,
1900 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301901
1902 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05301903 "LL_STATS_GET reqId = %d, MAC = %pM, paramIdMask = %d",
1904 linkLayerStatsGetReq.reqId, linkLayerStatsGetReq.macAddr,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301905 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301906
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301907 spin_lock(&hdd_context_lock);
1908 context = &pHddCtx->ll_stats_context;
1909 context->request_id = linkLayerStatsGetReq.reqId;
1910 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
1911 INIT_COMPLETION(context->response_event);
1912 spin_unlock(&hdd_context_lock);
1913
Sunil Duttc69bccb2014-05-26 21:30:20 +05301914 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301915 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301916 {
1917 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1918 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301919 return -EINVAL;
1920 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301921
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301922 rc = wait_for_completion_timeout(&context->response_event,
1923 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
1924 if (!rc)
1925 {
1926 hddLog(LOGE,
1927 FL("Target response timed out request id %d request bitmap 0x%x"),
1928 context->request_id, context->request_bitmap);
1929 return -ETIMEDOUT;
1930 }
1931
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301932 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301933 return 0;
1934}
1935
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301936static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1937 struct wireless_dev *wdev,
1938 const void *data,
1939 int data_len)
1940{
1941 int ret = 0;
1942
1943 vos_ssr_protect(__func__);
1944 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
1945 vos_ssr_unprotect(__func__);
1946
1947 return ret;
1948}
1949
Sunil Duttc69bccb2014-05-26 21:30:20 +05301950const struct
1951nla_policy
1952qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
1953{
1954 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
1955 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
1956 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
1957 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
1958};
1959
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301960static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
1961 struct wireless_dev *wdev,
1962 const void *data,
1963 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301964{
1965 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1966 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301967 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301968 struct net_device *dev = wdev->netdev;
1969 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1970 u32 statsClearReqMask;
1971 u8 stopReq;
1972 int status;
1973
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301974 ENTER();
1975
Sunil Duttc69bccb2014-05-26 21:30:20 +05301976 status = wlan_hdd_validate_context(pHddCtx);
1977 if (0 != status)
1978 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301979 return -EINVAL;
1980 }
1981
1982 if (NULL == pAdapter)
1983 {
1984 hddLog(VOS_TRACE_LEVEL_FATAL,
1985 "%s: HDD adapter is Null", __func__);
1986 return -ENODEV;
1987 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301988 /* check the LLStats Capability */
1989 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1990 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1991 {
1992 hddLog(VOS_TRACE_LEVEL_ERROR,
1993 FL("Enable LLStats Capability"));
1994 return -EINVAL;
1995 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301996
1997 if (!pAdapter->isLinkLayerStatsSet)
1998 {
1999 hddLog(VOS_TRACE_LEVEL_FATAL,
2000 "%s: isLinkLayerStatsSet : %d",
2001 __func__, pAdapter->isLinkLayerStatsSet);
2002 return -EINVAL;
2003 }
2004
2005 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2006 (struct nlattr *)data,
2007 data_len, qca_wlan_vendor_ll_clr_policy))
2008 {
2009 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2010 return -EINVAL;
2011 }
2012
2013 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2014
2015 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2016 {
2017 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2018 return -EINVAL;
2019
2020 }
2021
Sunil Duttc69bccb2014-05-26 21:30:20 +05302022
Dino Mycledf0a5d92014-07-04 09:41:55 +05302023 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302024 nla_get_u32(
2025 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2026
Dino Mycledf0a5d92014-07-04 09:41:55 +05302027 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302028 nla_get_u8(
2029 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2030
2031 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302032 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302033
Dino Mycled3d50022014-07-07 12:58:25 +05302034 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2035 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302036
2037 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik81a730c2015-09-14 14:49:52 +05302038 "LL_STATS_CLEAR reqId = %d, MAC = %pM,"
2039 "statsClearReqMask = 0x%X, stopReq = %d",
2040 linkLayerStatsClearReq.reqId,
2041 linkLayerStatsClearReq.macAddr,
2042 linkLayerStatsClearReq.statsClearReqMask,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302043 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302044
2045 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302046 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302047 {
2048 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302049 hdd_station_ctx_t *pHddStaCtx;
2050
2051 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2052 if (VOS_STATUS_SUCCESS !=
2053 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2054 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2055 {
2056 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2057 "WLANTL_ClearInterfaceStats Failed", __func__);
2058 return -EINVAL;
2059 }
2060 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2061 (statsClearReqMask & WIFI_STATS_IFACE)) {
2062 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2063 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2064 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2065 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2066 }
2067
Sunil Duttc69bccb2014-05-26 21:30:20 +05302068 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2069 2 * sizeof(u32) +
2070 NLMSG_HDRLEN);
2071
2072 if (temp_skbuff != NULL)
2073 {
2074
2075 if (nla_put_u32(temp_skbuff,
2076 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2077 statsClearReqMask) ||
2078 nla_put_u32(temp_skbuff,
2079 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2080 stopReq))
2081 {
2082 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2083 kfree_skb(temp_skbuff);
2084 return -EINVAL;
2085 }
2086 /* If the ask is to stop the stats collection as part of clear
2087 * (stopReq = 1) , ensure that no further requests of get
2088 * go to the firmware by having isLinkLayerStatsSet set to 0.
2089 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302090 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302091 * case the firmware is just asked to clear the statistics.
2092 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302093 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302094 pAdapter->isLinkLayerStatsSet = 0;
2095 return cfg80211_vendor_cmd_reply(temp_skbuff);
2096 }
2097 return -ENOMEM;
2098 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302099
2100 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302101 return -EINVAL;
2102}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302103static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2104 struct wireless_dev *wdev,
2105 const void *data,
2106 int data_len)
2107{
2108 int ret = 0;
2109
2110 vos_ssr_protect(__func__);
2111 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2112 vos_ssr_unprotect(__func__);
2113
2114 return ret;
2115
2116
2117}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302118#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2119
Dino Mycle6fb96c12014-06-10 11:52:40 +05302120#ifdef WLAN_FEATURE_EXTSCAN
2121static const struct nla_policy
2122wlan_hdd_extscan_config_policy
2123 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2124{
2125 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2126 { .type = NLA_U32 },
2127 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2128 { .type = NLA_U32 },
2129 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2130 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2131 { .type = NLA_U32 },
2132 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2133 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2134
2135 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2136 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2137 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2138 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2139 { .type = NLA_U8 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302140 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD] =
2141 { .type = NLA_U32 },
2142 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT] =
2143 { .type = NLA_U32 },
2144 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT] =
2145 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302146 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2147 { .type = NLA_U32 },
2148 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2149 { .type = NLA_U32 },
2150 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2151 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302152 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT] =
2153 { .type = NLA_U8 },
2154 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302155 { .type = NLA_U8 },
2156 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2157 { .type = NLA_U8 },
2158 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2159 { .type = NLA_U8 },
2160
2161 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2162 { .type = NLA_U32 },
2163 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2164 { .type = NLA_UNSPEC },
2165 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2166 { .type = NLA_S32 },
2167 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2168 { .type = NLA_S32 },
2169 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2170 { .type = NLA_U32 },
2171 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2172 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302173 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE] =
2174 { .type = NLA_U32 },
2175 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] =
2176 { .type = NLA_BINARY,
2177 .len = IEEE80211_MAX_SSID_LEN + 1 },
2178 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] =
Dino Mycle6fb96c12014-06-10 11:52:40 +05302179 { .type = NLA_U32 },
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302180 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID] =
2181 { .type = NLA_U32 },
2182 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND] =
2183 { .type = NLA_U8 },
2184 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW] =
2185 { .type = NLA_S32 },
2186 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH] =
2187 { .type = NLA_S32 },
2188 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CONFIGURATION_FLAGS] =
2189 { .type = NLA_U32 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05302190};
2191
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302192/**
2193 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2194 * @ctx: hdd global context
2195 * @data: capabilities data
2196 *
2197 * Return: none
2198 */
2199static void
2200wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302201{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302202 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302203 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302204 tSirEXTScanCapabilitiesEvent *data =
2205 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302206
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302207 ENTER();
2208
2209 if (wlan_hdd_validate_context(pHddCtx))
2210 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302211 return;
2212 }
2213
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302214 if (!pMsg)
2215 {
2216 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2217 return;
2218 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302219
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302220 vos_spin_lock_acquire(&hdd_context_lock);
2221
2222 context = &pHddCtx->ext_scan_context;
2223 /* validate response received from target*/
2224 if (context->request_id != data->requestId)
2225 {
2226 vos_spin_lock_release(&hdd_context_lock);
2227 hddLog(LOGE,
2228 FL("Target response id did not match: request_id %d resposne_id %d"),
2229 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302230 return;
2231 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302232 else
2233 {
2234 context->capability_response = *data;
2235 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302236 }
2237
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302238 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302239
Dino Mycle6fb96c12014-06-10 11:52:40 +05302240 return;
2241}
2242
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302243/*
2244 * define short names for the global vendor params
2245 * used by wlan_hdd_send_ext_scan_capability()
2246 */
2247#define PARAM_REQUEST_ID \
2248 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2249#define PARAM_STATUS \
2250 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2251#define MAX_SCAN_CACHE_SIZE \
2252 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2253#define MAX_SCAN_BUCKETS \
2254 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2255#define MAX_AP_CACHE_PER_SCAN \
2256 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2257#define MAX_RSSI_SAMPLE_SIZE \
2258 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2259#define MAX_SCAN_RPT_THRHOLD \
2260 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2261#define MAX_HOTLIST_BSSIDS \
2262 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2263#define MAX_BSSID_HISTORY_ENTRIES \
2264 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2265#define MAX_HOTLIST_SSIDS \
2266 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302267#define MAX_SIGNIFICANT_WIFI_CHANGE_APS \
2268 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302269
2270static int wlan_hdd_send_ext_scan_capability(void *ctx)
2271{
2272 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2273 struct sk_buff *skb = NULL;
2274 int ret;
2275 tSirEXTScanCapabilitiesEvent *data;
2276 tANI_U32 nl_buf_len;
2277
2278 ret = wlan_hdd_validate_context(pHddCtx);
2279 if (0 != ret)
2280 {
2281 return ret;
2282 }
2283
2284 data = &(pHddCtx->ext_scan_context.capability_response);
2285
2286 nl_buf_len = NLMSG_HDRLEN;
2287 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2288 (sizeof(data->status) + NLA_HDRLEN) +
2289 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2290 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2291 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2292 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2293 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2294 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2295 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2296 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2297
2298 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2299
2300 if (!skb)
2301 {
2302 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2303 return -ENOMEM;
2304 }
2305
2306 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2307 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2308 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2309 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2310 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2311 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2312 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2313 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2314
2315 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2316 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2317 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2318 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2319 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2320 data->maxApPerScan) ||
2321 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2322 data->maxRssiSampleSize) ||
2323 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2324 data->maxScanReportingThreshold) ||
2325 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2326 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2327 data->maxBsidHistoryEntries) ||
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302328 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs) ||
2329 nla_put_u32(skb, MAX_SIGNIFICANT_WIFI_CHANGE_APS, 0))
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302330 {
2331 hddLog(LOGE, FL("nla put fail"));
2332 goto nla_put_failure;
2333 }
2334
2335 cfg80211_vendor_cmd_reply(skb);
2336 return 0;
2337
2338nla_put_failure:
2339 kfree_skb(skb);
2340 return -EINVAL;;
2341}
2342
2343/*
2344 * done with short names for the global vendor params
2345 * used by wlan_hdd_send_ext_scan_capability()
2346 */
2347#undef PARAM_REQUEST_ID
2348#undef PARAM_STATUS
2349#undef MAX_SCAN_CACHE_SIZE
2350#undef MAX_SCAN_BUCKETS
2351#undef MAX_AP_CACHE_PER_SCAN
2352#undef MAX_RSSI_SAMPLE_SIZE
2353#undef MAX_SCAN_RPT_THRHOLD
2354#undef MAX_HOTLIST_BSSIDS
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302355#undef MAX_BSSID_HISTORY_ENTRIES
2356#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302357
2358static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2359{
2360 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2361 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302362 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302363 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302364
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302365 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302366
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302367 if (wlan_hdd_validate_context(pHddCtx))
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302368 return;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302369
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302370 if (!pMsg)
2371 {
2372 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302373 return;
2374 }
2375
Dino Mycle6fb96c12014-06-10 11:52:40 +05302376 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2377 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2378
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302379 context = &pHddCtx->ext_scan_context;
2380 spin_lock(&hdd_context_lock);
2381 if (context->request_id == pData->requestId) {
2382 context->response_status = pData->status ? -EINVAL : 0;
2383 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302384 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05302385 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302386
2387 /*
2388 * Store the Request ID for comparing with the requestID obtained
2389 * in other requests.HDD shall return a failure is the extscan_stop
2390 * request is issued with a different requestId as that of the
2391 * extscan_start request. Also, This requestId shall be used while
2392 * indicating the full scan results to the upper layers.
2393 * The requestId is stored with the assumption that the firmware
2394 * shall return the ext scan start request's requestId in ext scan
2395 * start response.
2396 */
2397 if (pData->status == 0)
2398 pMac->sme.extScanStartReqId = pData->requestId;
2399
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302400 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302401 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302402}
2403
2404
2405static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2406{
2407 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2408 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302409 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302410
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302411 ENTER();
2412
2413 if (wlan_hdd_validate_context(pHddCtx)){
2414 return;
2415 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302416
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302417 if (!pMsg)
2418 {
2419 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302420 return;
2421 }
2422
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302423 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2424 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302425
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302426 context = &pHddCtx->ext_scan_context;
2427 spin_lock(&hdd_context_lock);
2428 if (context->request_id == pData->requestId) {
2429 context->response_status = pData->status ? -EINVAL : 0;
2430 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302431 }
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05302432 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302433
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302434 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302435 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302436}
2437
Dino Mycle6fb96c12014-06-10 11:52:40 +05302438static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2439 void *pMsg)
2440{
2441 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302442 tpSirEXTScanSetBssidHotListRspParams pData =
2443 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302444 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302445
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302446 ENTER();
2447
2448 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302449 return;
2450 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302451
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302452 if (!pMsg)
2453 {
2454 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2455 return;
2456 }
2457
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302458 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2459 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302460
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302461 context = &pHddCtx->ext_scan_context;
2462 spin_lock(&hdd_context_lock);
2463 if (context->request_id == pData->requestId) {
2464 context->response_status = pData->status ? -EINVAL : 0;
2465 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302466 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302467 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302468
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302469 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302470 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302471}
2472
2473static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2474 void *pMsg)
2475{
2476 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302477 tpSirEXTScanResetBssidHotlistRspParams pData =
2478 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302479 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302480
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302481 ENTER();
2482
2483 if (wlan_hdd_validate_context(pHddCtx)) {
2484 return;
2485 }
2486 if (!pMsg)
2487 {
2488 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302489 return;
2490 }
2491
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302492 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2493 pData->status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302494
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302495 context = &pHddCtx->ext_scan_context;
2496 spin_lock(&hdd_context_lock);
2497 if (context->request_id == pData->requestId) {
2498 context->response_status = pData->status ? -EINVAL : 0;
2499 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302500 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05302501 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302502
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302503 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302504 return;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302505}
2506
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302507static void wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(void *ctx,
2508 void *pMsg)
2509{
2510 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2511 tpSirEXTScanSetSsidHotListRspParams pData =
2512 (tpSirEXTScanSetSsidHotListRspParams) pMsg;
2513 struct hdd_ext_scan_context *context;
2514
2515 if (wlan_hdd_validate_context(pHddCtx)){
2516 return;
2517 }
2518
2519 if (!pMsg)
2520 {
2521 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2522 return;
2523 }
2524
2525 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2526 pData->status);
2527
2528 context = &pHddCtx->ext_scan_context;
2529 spin_lock(&hdd_context_lock);
2530 if (context->request_id == pData->requestId) {
2531 context->response_status = pData->status ? -EINVAL : 0;
2532 complete(&context->response_event);
2533 }
2534 spin_unlock(&hdd_context_lock);
2535
2536 return;
2537}
2538
2539static void wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(void *ctx,
2540 void *pMsg)
2541{
2542 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2543 tpSirEXTScanResetSsidHotlistRspParams pData =
2544 (tpSirEXTScanResetSsidHotlistRspParams) pMsg;
2545 struct hdd_ext_scan_context *context;
2546
2547 if (wlan_hdd_validate_context(pHddCtx)) {
2548 return;
2549 }
2550 if (!pMsg)
2551 {
2552 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2553 return;
2554 }
2555
2556 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u Status %u", pData->requestId,
2557 pData->status);
2558
2559 context = &pHddCtx->ext_scan_context;
2560 spin_lock(&hdd_context_lock);
2561 if (context->request_id == pData->requestId) {
2562 context->response_status = pData->status ? -EINVAL : 0;
2563 complete(&context->response_event);
2564 }
2565 spin_unlock(&hdd_context_lock);
2566
2567 return;
2568}
2569
2570
Dino Mycle6fb96c12014-06-10 11:52:40 +05302571static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2572 void *pMsg)
2573{
2574 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2575 struct sk_buff *skb = NULL;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302576 tANI_U32 i = 0, j, resultsPerEvent, scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302577 tANI_S32 totalResults;
2578 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302579 tpSirWifiScanResult pSirWifiScanResult, head_ptr;
2580 struct hdd_ext_scan_context *context;
2581 bool ignore_cached_results = false;
2582 tExtscanCachedScanResult *result;
2583 struct nlattr *nla_results;
2584 tANI_U16 ieLength= 0;
2585 tANI_U8 *ie = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302586
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302587 ENTER();
2588
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302589 if (wlan_hdd_validate_context(pHddCtx))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302590 return;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302591
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302592 if (!pMsg)
2593 {
2594 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2595 return;
2596 }
2597
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302598 spin_lock(&hdd_context_lock);
2599 context = &pHddCtx->ext_scan_context;
2600 ignore_cached_results = context->ignore_cached_results;
2601 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302602
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302603 if (ignore_cached_results) {
2604 hddLog(LOGE,
2605 FL("Ignore the cached results received after timeout"));
2606 return;
2607 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302608
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302609 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id %u More Data %u No of scan ids %u",
2610 pData->requestId, pData->moreData, pData->scanResultSize);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302611
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302612 result = (tExtscanCachedScanResult *)&(pData->result);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302613
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302614 for (scan_id_index = 0; scan_id_index < pData->scanResultSize;
2615 scan_id_index++) {
2616 result+= scan_id_index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302617
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302618 totalResults = result->num_results;
2619 hddLog(VOS_TRACE_LEVEL_INFO, "scan_id %u flags %u Num results %u",
2620 result->scan_id, result->flags, totalResults);
2621 i = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302622
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302623 do{
2624 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2625 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2626 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302627
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302628 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
2629 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN);
2630
2631 if (!skb) {
2632 hddLog(VOS_TRACE_LEVEL_ERROR,
2633 FL("cfg80211_vendor_event_alloc failed"));
2634 return;
2635 }
2636
2637 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2638
2639 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2640 pData->requestId) ||
2641 nla_put_u32(skb,
2642 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2643 resultsPerEvent)) {
2644 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2645 goto fail;
2646 }
2647 if (nla_put_u8(skb,
2648 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2649 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302650 {
2651 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2652 goto fail;
2653 }
2654
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302655 if (nla_put_u32(skb,
2656 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2657 result->scan_id)) {
2658 hddLog(LOGE, FL("put fail"));
2659 goto fail;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302660 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302661
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05302662 nla_results = nla_nest_start(skb,
2663 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_LIST);
2664 if (!nla_results)
2665 goto fail;
2666
2667 if (resultsPerEvent) {
2668 struct nlattr *aps;
2669 struct nlattr *nla_result;
2670
2671 nla_result = nla_nest_start(skb, scan_id_index);
2672 if(!nla_result)
2673 goto fail;
2674
2675 if (nla_put_u32(skb,
2676 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_SCAN_ID,
2677 result->scan_id) ||
2678 nla_put_u32(skb,
2679 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CACHED_RESULTS_FLAGS,
2680 result->flags) ||
2681 nla_put_u32(skb,
2682 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2683 totalResults)) {
2684 hddLog(LOGE, FL("put fail"));
2685 goto fail;
2686 }
2687
2688 aps = nla_nest_start(skb,
2689 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2690 if (!aps)
2691 {
2692 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2693 goto fail;
2694 }
2695
2696 head_ptr = (tpSirWifiScanResult) &(result->ap);
2697
2698 for (j = 0; j < resultsPerEvent; j++, i++) {
2699 struct nlattr *ap;
2700 pSirWifiScanResult = head_ptr + i;
2701
2702 /*
2703 * Firmware returns timestamp from WiFi turn ON till
2704 * BSSID was cached (in seconds). Add this with
2705 * time gap between system boot up to WiFi turn ON
2706 * to derive the time since boot when the
2707 * BSSID was cached.
2708 */
2709 pSirWifiScanResult->ts += pHddCtx->wifi_turn_on_time_since_boot;
2710 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2711 "Ssid (%s)"
2712 "Bssid: %pM "
2713 "Channel (%u)"
2714 "Rssi (%d)"
2715 "RTT (%u)"
2716 "RTT_SD (%u)"
2717 "Beacon Period %u"
2718 "Capability 0x%x "
2719 "Ie length %d",
2720 i,
2721 pSirWifiScanResult->ts,
2722 pSirWifiScanResult->ssid,
2723 pSirWifiScanResult->bssid,
2724 pSirWifiScanResult->channel,
2725 pSirWifiScanResult->rssi,
2726 pSirWifiScanResult->rtt,
2727 pSirWifiScanResult->rtt_sd,
2728 pSirWifiScanResult->beaconPeriod,
2729 pSirWifiScanResult->capability,
2730 ieLength);
2731
2732 ap = nla_nest_start(skb, j + 1);
2733 if (!ap)
2734 {
2735 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2736 goto fail;
2737 }
2738
2739 if (nla_put_u64(skb,
2740 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2741 pSirWifiScanResult->ts) )
2742 {
2743 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2744 goto fail;
2745 }
2746 if (nla_put(skb,
2747 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2748 sizeof(pSirWifiScanResult->ssid),
2749 pSirWifiScanResult->ssid) )
2750 {
2751 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2752 goto fail;
2753 }
2754 if (nla_put(skb,
2755 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2756 sizeof(pSirWifiScanResult->bssid),
2757 pSirWifiScanResult->bssid) )
2758 {
2759 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2760 goto fail;
2761 }
2762 if (nla_put_u32(skb,
2763 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2764 pSirWifiScanResult->channel) )
2765 {
2766 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2767 goto fail;
2768 }
2769 if (nla_put_s32(skb,
2770 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2771 pSirWifiScanResult->rssi) )
2772 {
2773 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2774 goto fail;
2775 }
2776 if (nla_put_u32(skb,
2777 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2778 pSirWifiScanResult->rtt) )
2779 {
2780 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2781 goto fail;
2782 }
2783 if (nla_put_u32(skb,
2784 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2785 pSirWifiScanResult->rtt_sd))
2786 {
2787 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2788 goto fail;
2789 }
2790 if (nla_put_u32(skb,
2791 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
2792 pSirWifiScanResult->beaconPeriod))
2793 {
2794 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2795 goto fail;
2796 }
2797 if (nla_put_u32(skb,
2798 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
2799 pSirWifiScanResult->capability))
2800 {
2801 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2802 goto fail;
2803 }
2804 if (nla_put_u32(skb,
2805 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
2806 ieLength))
2807 {
2808 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2809 goto fail;
2810 }
2811
2812 if (ieLength)
2813 if (nla_put(skb,
2814 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
2815 ieLength, ie)) {
2816 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2817 goto fail;
2818 }
2819
2820 nla_nest_end(skb, ap);
2821 }
2822 nla_nest_end(skb, aps);
2823 nla_nest_end(skb, nla_result);
2824 }
2825
2826 nla_nest_end(skb, nla_results);
2827
2828 cfg80211_vendor_cmd_reply(skb);
2829
2830 } while (totalResults > 0);
2831 }
2832
2833 if (!pData->moreData) {
2834 spin_lock(&hdd_context_lock);
2835 context->response_status = 0;
2836 complete(&context->response_event);
2837 spin_unlock(&hdd_context_lock);
2838 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302839
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302840 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302841 return;
2842fail:
2843 kfree_skb(skb);
2844 return;
2845}
2846
2847static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2848 void *pMsg)
2849{
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302850 tpSirEXTScanHotlistMatch pData = (tpSirEXTScanHotlistMatch) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302851 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2852 struct sk_buff *skb = NULL;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302853 tANI_U32 i, index;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302854
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302855 ENTER();
2856
2857 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302858 hddLog(LOGE,
2859 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302860 return;
2861 }
2862 if (!pMsg)
2863 {
2864 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302865 return;
2866 }
2867
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302868 if (pData->bss_found)
2869 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX;
2870 else
2871 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST_INDEX;
2872
Dino Mycle6fb96c12014-06-10 11:52:40 +05302873 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302874#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2875 NULL,
2876#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302877 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302878 index, GFP_KERNEL);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302879
2880 if (!skb) {
2881 hddLog(VOS_TRACE_LEVEL_ERROR,
2882 FL("cfg80211_vendor_event_alloc failed"));
2883 return;
2884 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302885
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302886 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2887 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numHotlistBss);
2888 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2889 hddLog(VOS_TRACE_LEVEL_INFO, "ap_found %u", pData->bss_found);
2890
2891 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302892 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2893 "Ssid (%s) "
2894 "Bssid (" MAC_ADDRESS_STR ") "
2895 "Channel (%u) "
2896 "Rssi (%d) "
2897 "RTT (%u) "
2898 "RTT_SD (%u) ",
2899 i,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302900 pData->bssHotlist[i].ts,
2901 pData->bssHotlist[i].ssid,
2902 MAC_ADDR_ARRAY(pData->bssHotlist[i].bssid),
2903 pData->bssHotlist[i].channel,
2904 pData->bssHotlist[i].rssi,
2905 pData->bssHotlist[i].rtt,
2906 pData->bssHotlist[i].rtt_sd);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302907 }
2908
2909 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2910 pData->requestId) ||
2911 nla_put_u32(skb,
2912 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302913 pData->numHotlistBss)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302914 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2915 goto fail;
2916 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302917 if (pData->numHotlistBss) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302918 struct nlattr *aps;
2919
2920 aps = nla_nest_start(skb,
2921 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2922 if (!aps)
2923 goto fail;
2924
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302925 for (i = 0; i < pData->numHotlistBss; i++) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302926 struct nlattr *ap;
2927
2928 ap = nla_nest_start(skb, i + 1);
2929 if (!ap)
2930 goto fail;
2931
2932 if (nla_put_u64(skb,
2933 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302934 pData->bssHotlist[i].ts) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302935 nla_put(skb,
2936 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302937 sizeof(pData->bssHotlist[i].ssid),
2938 pData->bssHotlist[i].ssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302939 nla_put(skb,
2940 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302941 sizeof(pData->bssHotlist[i].bssid),
2942 pData->bssHotlist[i].bssid) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302943 nla_put_u32(skb,
2944 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302945 pData->bssHotlist[i].channel) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302946 nla_put_s32(skb,
2947 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302948 pData->bssHotlist[i].rssi) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302949 nla_put_u32(skb,
2950 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302951 pData->bssHotlist[i].rtt) ||
Dino Mycle6fb96c12014-06-10 11:52:40 +05302952 nla_put_u32(skb,
2953 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05302954 pData->bssHotlist[i].rtt_sd))
Dino Mycle6fb96c12014-06-10 11:52:40 +05302955 goto fail;
2956
2957 nla_nest_end(skb, ap);
2958 }
2959 nla_nest_end(skb, aps);
2960
2961 if (nla_put_u8(skb,
2962 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2963 pData->moreData))
2964 goto fail;
2965 }
2966
2967 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302968 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302969 return;
2970
2971fail:
2972 kfree_skb(skb);
2973 return;
2974
2975}
Dino Mycle6fb96c12014-06-10 11:52:40 +05302976
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05302977/**
2978 * wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind() -
2979 * Handle an SSID hotlist match event
2980 * @ctx: HDD context registered with SME
2981 * @event: The SSID hotlist match event
2982 *
2983 * This function will take an SSID match event that was generated by
2984 * firmware and will convert it into a cfg80211 vendor event which is
2985 * sent to userspace.
2986 *
2987 * Return: none
2988 */
2989static void
2990wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(void *ctx,
2991 void *pMsg)
2992{
2993 hdd_context_t *hdd_ctx = ctx;
2994 struct sk_buff *skb;
2995 tANI_U32 i, index;
2996 tpSirEXTScanSsidHotlistMatch pData = (tpSirEXTScanSsidHotlistMatch) pMsg;
2997
2998 ENTER();
2999
3000 if (wlan_hdd_validate_context(hdd_ctx)) {
3001 hddLog(LOGE,
3002 FL("HDD context is not valid or response"));
3003 return;
3004 }
3005 if (!pMsg)
3006 {
3007 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3008 return;
3009 }
3010
3011 if (pData->ssid_found) {
3012 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX;
3013 hddLog(LOG1, "SSID hotlist found");
3014 } else {
3015 index = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX;
3016 hddLog(LOG1, "SSID hotlist lost");
3017 }
3018
3019 skb = cfg80211_vendor_event_alloc(hdd_ctx->wiphy,
3020#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3021 NULL,
3022#endif
3023 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3024 index, GFP_KERNEL);
3025
3026 if (!skb) {
3027 hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed"));
3028 return;
3029 }
3030 hddLog(LOG1, "Req Id %u, Num of SSIDs %u, More Data (%u)",
3031 pData->requestId, pData->numHotlistSsid, pData->moreData);
3032
3033 for (i = 0; i < pData->numHotlistSsid; i++) {
3034 hddLog(LOG1, "[i=%d] Timestamp %llu "
3035 "Ssid: %s "
3036 "Bssid (" MAC_ADDRESS_STR ") "
3037 "Channel %u "
3038 "Rssi %d "
3039 "RTT %u "
3040 "RTT_SD %u",
3041 i,
3042 pData->ssidHotlist[i].ts,
3043 pData->ssidHotlist[i].ssid,
3044 MAC_ADDR_ARRAY(pData->ssidHotlist[i].bssid),
3045 pData->ssidHotlist[i].channel,
3046 pData->ssidHotlist[i].rssi,
3047 pData->ssidHotlist[i].rtt,
3048 pData->ssidHotlist[i].rtt_sd);
3049 }
3050
3051 if (nla_put_u32(skb,
3052 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3053 pData->requestId) ||
3054 nla_put_u32(skb,
3055 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3056 pData->numHotlistSsid)) {
3057 hddLog(LOGE, FL("put fail"));
3058 goto fail;
3059 }
3060
3061 if (pData->numHotlistSsid) {
3062 struct nlattr *aps;
3063 aps = nla_nest_start(skb,
3064 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3065 if (!aps) {
3066 hddLog(LOGE, FL("nest fail"));
3067 goto fail;
3068 }
3069
3070 for (i = 0; i < pData->numHotlistSsid; i++) {
3071 struct nlattr *ap;
3072
3073 ap = nla_nest_start(skb, i);
3074 if (!ap) {
3075 hddLog(LOGE, FL("nest fail"));
3076 goto fail;
3077 }
3078
3079 if (nla_put_u64(skb,
3080 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3081 pData->ssidHotlist[i].ts) ||
3082 nla_put(skb,
3083 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3084 sizeof(pData->ssidHotlist[i].ssid),
3085 pData->ssidHotlist[i].ssid) ||
3086 nla_put(skb,
3087 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3088 sizeof(pData->ssidHotlist[i].bssid),
3089 pData->ssidHotlist[i].bssid) ||
3090 nla_put_u32(skb,
3091 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3092 pData->ssidHotlist[i].channel) ||
3093 nla_put_s32(skb,
3094 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3095 pData->ssidHotlist[i].rssi) ||
3096 nla_put_u32(skb,
3097 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3098 pData->ssidHotlist[i].rtt) ||
3099 nla_put_u32(skb,
3100 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3101 pData->ssidHotlist[i].rtt_sd)) {
3102 hddLog(LOGE, FL("put fail"));
3103 goto fail;
3104 }
3105 nla_nest_end(skb, ap);
3106 }
3107 nla_nest_end(skb, aps);
3108
3109 if (nla_put_u8(skb,
3110 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3111 pData->moreData)) {
3112 hddLog(LOGE, FL("put fail"));
3113 goto fail;
3114 }
3115 }
3116
3117 cfg80211_vendor_event(skb, GFP_KERNEL);
3118 return;
3119
3120fail:
3121 kfree_skb(skb);
3122 return;
3123
3124}
3125
3126
Dino Mycle6fb96c12014-06-10 11:52:40 +05303127static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3128 void *pMsg)
3129{
3130 struct sk_buff *skb;
3131 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3132 tpSirWifiFullScanResultEvent pData =
3133 (tpSirWifiFullScanResultEvent) (pMsg);
3134
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303135 ENTER();
3136
3137 if (wlan_hdd_validate_context(pHddCtx)) {
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303138 hddLog(LOGE,
3139 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303140 return;
3141 }
3142 if (!pMsg)
3143 {
3144 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303145 return;
3146 }
3147
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303148 /*
3149 * If the full scan result including IE data exceeds NL 4K size
3150 * limitation, drop that beacon/probe rsp frame.
3151 */
3152 if ((sizeof(*pData) + pData->ieLength) >= EXTSCAN_EVENT_BUF_SIZE) {
3153 hddLog(LOGE, FL("Frame exceeded NL size limilation, drop it!"));
3154 return;
3155 }
3156
Dino Mycle6fb96c12014-06-10 11:52:40 +05303157 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303158#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3159 NULL,
3160#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303161 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3162 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3163 GFP_KERNEL);
3164
3165 if (!skb) {
3166 hddLog(VOS_TRACE_LEVEL_ERROR,
3167 FL("cfg80211_vendor_event_alloc failed"));
3168 return;
3169 }
3170
Dino Mycle6fb96c12014-06-10 11:52:40 +05303171 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3172 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3173 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3174 "Ssid (%s)"
3175 "Bssid (" MAC_ADDRESS_STR ")"
3176 "Channel (%u)"
3177 "Rssi (%d)"
3178 "RTT (%u)"
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303179 "RTT_SD (%u)"
3180 "Bcn Period %d"
3181 "Capability 0x%X "),
Dino Mycle6fb96c12014-06-10 11:52:40 +05303182 pData->ap.ts,
3183 pData->ap.ssid,
3184 MAC_ADDR_ARRAY(pData->ap.bssid),
3185 pData->ap.channel,
3186 pData->ap.rssi,
3187 pData->ap.rtt,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303188 pData->ap.rtt_sd,
3189 pData->ap.beaconPeriod,
3190 pData->ap.capability);
3191
Dino Mycle6fb96c12014-06-10 11:52:40 +05303192 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3193 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3194 pData->requestId) ||
3195 nla_put_u64(skb,
3196 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3197 pData->ap.ts) ||
3198 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3199 sizeof(pData->ap.ssid),
3200 pData->ap.ssid) ||
3201 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3202 WNI_CFG_BSSID_LEN,
3203 pData->ap.bssid) ||
3204 nla_put_u32(skb,
3205 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3206 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303207 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303208 pData->ap.rssi) ||
3209 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3210 pData->ap.rtt) ||
3211 nla_put_u32(skb,
3212 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3213 pData->ap.rtt_sd) ||
3214 nla_put_u16(skb,
3215 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3216 pData->ap.beaconPeriod) ||
3217 nla_put_u16(skb,
3218 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3219 pData->ap.capability) ||
3220 nla_put_u32(skb,
3221 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303222 pData->ieLength) ||
3223 nla_put_u8(skb,
3224 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3225 pData->moreData))
Dino Mycle6fb96c12014-06-10 11:52:40 +05303226 {
3227 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3228 goto nla_put_failure;
3229 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303230
3231 if (pData->ieLength) {
3232 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3233 pData->ieLength,
3234 pData->ie))
3235 {
3236 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3237 goto nla_put_failure;
3238 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303239 }
3240
3241 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303242 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303243 return;
3244
3245nla_put_failure:
3246 kfree_skb(skb);
3247 return;
3248}
3249
3250static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3251 void *pMsg)
3252{
3253 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3254 struct sk_buff *skb = NULL;
3255 tpSirEXTScanResultsAvailableIndParams pData =
3256 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3257
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303258 ENTER();
3259
3260 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303261 hddLog(LOGE,
3262 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303263 return;
3264 }
3265 if (!pMsg)
3266 {
3267 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303268 return;
3269 }
3270
3271 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303272#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3273 NULL,
3274#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303275 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3276 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3277 GFP_KERNEL);
3278
3279 if (!skb) {
3280 hddLog(VOS_TRACE_LEVEL_ERROR,
3281 FL("cfg80211_vendor_event_alloc failed"));
3282 return;
3283 }
3284
Dino Mycle6fb96c12014-06-10 11:52:40 +05303285 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3286 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3287 pData->numResultsAvailable);
3288 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3289 pData->requestId) ||
3290 nla_put_u32(skb,
3291 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3292 pData->numResultsAvailable)) {
3293 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3294 goto nla_put_failure;
3295 }
3296
3297 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303298 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303299 return;
3300
3301nla_put_failure:
3302 kfree_skb(skb);
3303 return;
3304}
3305
3306static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3307{
3308 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3309 struct sk_buff *skb = NULL;
3310 tpSirEXTScanProgressIndParams pData =
3311 (tpSirEXTScanProgressIndParams) pMsg;
3312
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303313 ENTER();
3314
3315 if (wlan_hdd_validate_context(pHddCtx)){
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303316 hddLog(LOGE,
3317 FL("HDD context is not valid or response"));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303318 return;
3319 }
3320 if (!pMsg)
3321 {
3322 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303323 return;
3324 }
3325
3326 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303327#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3328 NULL,
3329#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303330 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3331 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3332 GFP_KERNEL);
3333
3334 if (!skb) {
3335 hddLog(VOS_TRACE_LEVEL_ERROR,
3336 FL("cfg80211_vendor_event_alloc failed"));
3337 return;
3338 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303339 hddLog(VOS_TRACE_LEVEL_INFO, FL("Request Id (%u) "), pData->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303340 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3341 pData->extScanEventType);
3342 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3343 pData->status);
3344
3345 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3346 pData->extScanEventType) ||
3347 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303348 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3349 pData->requestId) ||
3350 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303351 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3352 pData->status)) {
3353 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3354 goto nla_put_failure;
3355 }
3356
3357 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303358 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303359 return;
3360
3361nla_put_failure:
3362 kfree_skb(skb);
3363 return;
3364}
3365
3366void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3367 void *pMsg)
3368{
3369 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3370
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303371 ENTER();
3372
Dino Mycle6fb96c12014-06-10 11:52:40 +05303373 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303374 return;
3375 }
3376
3377 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3378
3379
3380 switch(evType) {
3381 case SIR_HAL_EXTSCAN_START_RSP:
3382 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3383 break;
3384
3385 case SIR_HAL_EXTSCAN_STOP_RSP:
3386 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3387 break;
3388 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3389 /* There is no need to send this response to upper layer
3390 Just log the message */
3391 hddLog(VOS_TRACE_LEVEL_INFO,
3392 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3393 break;
3394 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3395 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3396 break;
3397
3398 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3399 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3400 break;
3401
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303402 case SIR_HAL_EXTSCAN_SET_SSID_HOTLIST_RSP:
3403 wlan_hdd_cfg80211_extscan_set_ssid_hotlist_rsp(ctx, pMsg);
3404 break;
3405
3406 case SIR_HAL_EXTSCAN_RESET_SSID_HOTLIST_RSP:
3407 wlan_hdd_cfg80211_extscan_reset_ssid_hotlist_rsp(ctx, pMsg);
3408 break;
3409
Dino Mycle6fb96c12014-06-10 11:52:40 +05303410 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303411 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303412 break;
3413 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3414 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3415 break;
3416 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3417 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3418 break;
3419 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3420 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3421 break;
3422 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3423 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3424 break;
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303425 case SIR_HAL_EXTSCAN_SSID_HOTLIST_MATCH_IND:
3426 wlan_hdd_cfg80211_extscan_hotlist_ssid_match_ind(ctx, pMsg);
3427 break;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303428 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3429 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3430 break;
3431 default:
3432 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3433 break;
3434 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303435 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303436}
3437
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303438static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3439 struct wireless_dev *wdev,
3440 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303441{
Dino Myclee8843b32014-07-04 14:21:45 +05303442 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303443 struct net_device *dev = wdev->netdev;
3444 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3445 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3446 struct nlattr
3447 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3448 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303449 struct hdd_ext_scan_context *context;
3450 unsigned long rc;
3451 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303452
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303453 ENTER();
3454
Dino Mycle6fb96c12014-06-10 11:52:40 +05303455 status = wlan_hdd_validate_context(pHddCtx);
3456 if (0 != status)
3457 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303458 return -EINVAL;
3459 }
Dino Myclee8843b32014-07-04 14:21:45 +05303460 /* check the EXTScan Capability */
3461 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3462 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3463 {
3464 hddLog(VOS_TRACE_LEVEL_ERROR,
3465 FL("EXTScan not enabled/supported by Firmware"));
3466 return -EINVAL;
3467 }
3468
Dino Mycle6fb96c12014-06-10 11:52:40 +05303469 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3470 data, dataLen,
3471 wlan_hdd_extscan_config_policy)) {
3472 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3473 return -EINVAL;
3474 }
3475
3476 /* Parse and fetch request Id */
3477 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3478 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3479 return -EINVAL;
3480 }
3481
Dino Myclee8843b32014-07-04 14:21:45 +05303482 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303483 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303484 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303485
Dino Myclee8843b32014-07-04 14:21:45 +05303486 reqMsg.sessionId = pAdapter->sessionId;
3487 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303488
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303489 vos_spin_lock_acquire(&hdd_context_lock);
3490 context = &pHddCtx->ext_scan_context;
3491 context->request_id = reqMsg.requestId;
3492 INIT_COMPLETION(context->response_event);
3493 vos_spin_lock_release(&hdd_context_lock);
3494
Dino Myclee8843b32014-07-04 14:21:45 +05303495 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303496 if (!HAL_STATUS_SUCCESS(status)) {
3497 hddLog(VOS_TRACE_LEVEL_ERROR,
3498 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303499 return -EINVAL;
3500 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303501
3502 rc = wait_for_completion_timeout(&context->response_event,
3503 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3504 if (!rc) {
3505 hddLog(LOGE, FL("Target response timed out"));
3506 return -ETIMEDOUT;
3507 }
3508
3509 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3510 if (ret)
3511 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3512
3513 return ret;
3514
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303515 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303516 return 0;
3517}
3518
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303519static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3520 struct wireless_dev *wdev,
3521 const void *data, int dataLen)
3522{
3523 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303524
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303525 vos_ssr_protect(__func__);
3526 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3527 vos_ssr_unprotect(__func__);
3528
3529 return ret;
3530}
3531
3532static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3533 struct wireless_dev *wdev,
3534 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303535{
Dino Myclee8843b32014-07-04 14:21:45 +05303536 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303537 struct net_device *dev = wdev->netdev;
3538 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3539 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3540 struct nlattr
3541 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3542 eHalStatus status;
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303543 struct hdd_ext_scan_context *context;
3544 unsigned long rc;
3545 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303546
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303547 ENTER();
3548
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303549 if (VOS_FTM_MODE == hdd_get_conparam()) {
3550 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3551 return -EINVAL;
3552 }
3553
Dino Mycle6fb96c12014-06-10 11:52:40 +05303554 status = wlan_hdd_validate_context(pHddCtx);
3555 if (0 != status)
3556 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303557 return -EINVAL;
3558 }
Dino Myclee8843b32014-07-04 14:21:45 +05303559 /* check the EXTScan Capability */
3560 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3561 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3562 {
3563 hddLog(VOS_TRACE_LEVEL_ERROR,
3564 FL("EXTScan not enabled/supported by Firmware"));
3565 return -EINVAL;
3566 }
3567
Dino Mycle6fb96c12014-06-10 11:52:40 +05303568 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3569 data, dataLen,
3570 wlan_hdd_extscan_config_policy)) {
3571 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3572 return -EINVAL;
3573 }
3574 /* Parse and fetch request Id */
3575 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3576 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3577 return -EINVAL;
3578 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303579
Dino Myclee8843b32014-07-04 14:21:45 +05303580 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303581 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3582
Dino Myclee8843b32014-07-04 14:21:45 +05303583 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303584
Dino Myclee8843b32014-07-04 14:21:45 +05303585 reqMsg.sessionId = pAdapter->sessionId;
3586 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303587
3588 /* Parse and fetch flush parameter */
3589 if (!tb
3590 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3591 {
3592 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3593 goto failed;
3594 }
Dino Myclee8843b32014-07-04 14:21:45 +05303595 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303596 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3597
Dino Myclee8843b32014-07-04 14:21:45 +05303598 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303599
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303600 spin_lock(&hdd_context_lock);
3601 context = &pHddCtx->ext_scan_context;
3602 context->request_id = reqMsg.requestId;
3603 context->ignore_cached_results = false;
3604 INIT_COMPLETION(context->response_event);
3605 spin_unlock(&hdd_context_lock);
3606
Dino Myclee8843b32014-07-04 14:21:45 +05303607 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303608 if (!HAL_STATUS_SUCCESS(status)) {
3609 hddLog(VOS_TRACE_LEVEL_ERROR,
3610 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303611 return -EINVAL;
3612 }
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303613
3614 rc = wait_for_completion_timeout(&context->response_event,
3615 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3616 if (!rc) {
3617 hddLog(LOGE, FL("Target response timed out"));
3618 retval = -ETIMEDOUT;
3619 spin_lock(&hdd_context_lock);
3620 context->ignore_cached_results = true;
3621 spin_unlock(&hdd_context_lock);
3622 } else {
3623 spin_lock(&hdd_context_lock);
3624 retval = context->response_status;
3625 spin_unlock(&hdd_context_lock);
3626 }
3627
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303628 EXIT();
Padma, Santhosh Kumare1b8a942015-08-25 12:44:24 +05303629 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303630
3631failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303632 return -EINVAL;
3633}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303634static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3635 struct wireless_dev *wdev,
3636 const void *data, int dataLen)
3637{
3638 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303639
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303640 vos_ssr_protect(__func__);
3641 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3642 vos_ssr_unprotect(__func__);
3643
3644 return ret;
3645}
3646
3647static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303648 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303649 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303650{
3651 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3652 struct net_device *dev = wdev->netdev;
3653 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3654 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3655 struct nlattr
3656 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3657 struct nlattr
3658 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3659 struct nlattr *apTh;
3660 eHalStatus status;
3661 tANI_U8 i = 0;
3662 int rem;
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303663 struct hdd_ext_scan_context *context;
3664 tANI_U32 request_id;
3665 unsigned long rc;
3666 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303667
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303668 ENTER();
3669
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303670 if (VOS_FTM_MODE == hdd_get_conparam()) {
3671 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3672 return -EINVAL;
3673 }
3674
Dino Mycle6fb96c12014-06-10 11:52:40 +05303675 status = wlan_hdd_validate_context(pHddCtx);
3676 if (0 != status)
3677 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303678 return -EINVAL;
3679 }
Dino Myclee8843b32014-07-04 14:21:45 +05303680 /* check the EXTScan Capability */
3681 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3682 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3683 {
3684 hddLog(VOS_TRACE_LEVEL_ERROR,
3685 FL("EXTScan not enabled/supported by Firmware"));
3686 return -EINVAL;
3687 }
3688
Dino Mycle6fb96c12014-06-10 11:52:40 +05303689 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3690 data, dataLen,
3691 wlan_hdd_extscan_config_policy)) {
3692 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3693 return -EINVAL;
3694 }
3695
3696 /* Parse and fetch request Id */
3697 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3698 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3699 return -EINVAL;
3700 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303701 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3702 vos_mem_malloc(sizeof(*pReqMsg));
3703 if (!pReqMsg) {
3704 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3705 return -ENOMEM;
3706 }
3707
Dino Myclee8843b32014-07-04 14:21:45 +05303708
Dino Mycle6fb96c12014-06-10 11:52:40 +05303709 pReqMsg->requestId = nla_get_u32(
3710 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3711 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3712
3713 /* Parse and fetch number of APs */
3714 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3715 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3716 goto fail;
3717 }
3718
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303719 /* Parse and fetch lost ap sample size */
3720 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]) {
3721 hddLog(LOGE, FL("attr lost ap sample size failed"));
3722 goto fail;
3723 }
3724
3725 pReqMsg->lostBssidSampleSize = nla_get_u32(
3726 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_LOST_AP_SAMPLE_SIZE]);
3727 hddLog(LOG1, FL("Lost ap sample size %d"), pReqMsg->lostBssidSampleSize);
3728
Dino Mycle6fb96c12014-06-10 11:52:40 +05303729 pReqMsg->sessionId = pAdapter->sessionId;
3730 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3731
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303732 pReqMsg->numBssid = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303733 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303734 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numBssid);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303735
3736 nla_for_each_nested(apTh,
3737 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3738 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3739 nla_data(apTh), nla_len(apTh),
3740 NULL)) {
3741 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3742 goto fail;
3743 }
3744
3745 /* Parse and fetch MAC address */
3746 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3747 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3748 goto fail;
3749 }
3750 memcpy(pReqMsg->ap[i].bssid, nla_data(
3751 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3752 sizeof(tSirMacAddr));
3753 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3754
3755 /* Parse and fetch low RSSI */
3756 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3757 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3758 goto fail;
3759 }
3760 pReqMsg->ap[i].low = nla_get_s32(
3761 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3762 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3763
3764 /* Parse and fetch high RSSI */
3765 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3766 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3767 goto fail;
3768 }
3769 pReqMsg->ap[i].high = nla_get_s32(
3770 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3771 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3772 pReqMsg->ap[i].high);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303773 i++;
3774 }
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303775
3776 context = &pHddCtx->ext_scan_context;
3777 spin_lock(&hdd_context_lock);
3778 INIT_COMPLETION(context->response_event);
3779 context->request_id = request_id = pReqMsg->requestId;
3780 spin_unlock(&hdd_context_lock);
3781
Dino Mycle6fb96c12014-06-10 11:52:40 +05303782 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3783 if (!HAL_STATUS_SUCCESS(status)) {
3784 hddLog(VOS_TRACE_LEVEL_ERROR,
3785 FL("sme_SetBssHotlist failed(err=%d)"), status);
3786 vos_mem_free(pReqMsg);
3787 return -EINVAL;
3788 }
3789
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303790 /* request was sent -- wait for the response */
3791 rc = wait_for_completion_timeout(&context->response_event,
3792 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3793
3794 if (!rc) {
3795 hddLog(LOGE, FL("sme_SetBssHotlist timed out"));
3796 retval = -ETIMEDOUT;
3797 } else {
3798 spin_lock(&hdd_context_lock);
3799 if (context->request_id == request_id)
3800 retval = context->response_status;
3801 else
3802 retval = -EINVAL;
3803 spin_unlock(&hdd_context_lock);
3804 }
3805
Dino Myclee8843b32014-07-04 14:21:45 +05303806 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303807 EXIT();
Padma, Santhosh Kumar37f4fd12015-08-19 14:37:37 +05303808 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303809
3810fail:
3811 vos_mem_free(pReqMsg);
3812 return -EINVAL;
3813}
3814
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303815static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3816 struct wireless_dev *wdev,
3817 const void *data, int dataLen)
3818{
3819 int ret = 0;
3820
3821 vos_ssr_protect(__func__);
3822 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3823 dataLen);
3824 vos_ssr_unprotect(__func__);
3825
3826 return ret;
3827}
3828
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05303829/*
3830 * define short names for the global vendor params
3831 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
3832 */
3833#define PARAM_MAX \
3834QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
3835#define PARAM_REQUEST_ID \
3836QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
3837#define PARAMS_LOST_SSID_SAMPLE_SIZE \
3838QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE
3839#define PARAMS_NUM_SSID \
3840QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_NUM_SSID
3841#define THRESHOLD_PARAM \
3842QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM
3843#define PARAM_SSID \
3844QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_SSID
3845#define PARAM_BAND \
3846QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_BAND
3847#define PARAM_RSSI_LOW \
3848QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_LOW
3849#define PARAM_RSSI_HIGH \
3850QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_THRESHOLD_PARAM_RSSI_HIGH
3851
3852/**
3853 * __wlan_hdd_cfg80211_extscan_set_ssid_hotlist() - set ssid hot list
3854 * @wiphy: Pointer to wireless phy
3855 * @wdev: Pointer to wireless device
3856 * @data: Pointer to data
3857 * @data_len: Data length
3858 *
3859 * Return: 0 on success, negative errno on failure
3860 */
3861static int
3862__wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
3863 struct wireless_dev *wdev,
3864 const void *data,
3865 int data_len)
3866{
3867 tSirEXTScanSetSsidHotListReqParams *request;
3868 struct net_device *dev = wdev->netdev;
3869 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
3870 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
3871 struct nlattr *tb[PARAM_MAX + 1];
3872 struct nlattr *tb2[PARAM_MAX + 1];
3873 struct nlattr *ssids;
3874 struct hdd_ext_scan_context *context;
3875 uint32_t request_id;
3876 char ssid_string[SIR_MAC_MAX_SSID_LENGTH + 1] = {'\0'};
3877 int ssid_len;
3878 eHalStatus status;
3879 int i, rem, retval;
3880 unsigned long rc;
3881
3882 ENTER();
3883
3884 if (VOS_FTM_MODE == hdd_get_conparam()) {
3885 hddLog(LOGE, FL("Command not allowed in FTM mode"));
3886 return -EINVAL;
3887 }
3888
3889 retval = wlan_hdd_validate_context(hdd_ctx);
3890 if (0 != retval) {
3891 hddLog(LOGE, FL("HDD context is not valid"));
3892 return -EINVAL;
3893 }
3894
3895 /* check the EXTScan Capability */
3896 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
3897 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3898 {
3899 hddLog(VOS_TRACE_LEVEL_ERROR,
3900 FL("EXTScan not enabled/supported by Firmware"));
3901 return -EINVAL;
3902 }
3903
3904 if (nla_parse(tb, PARAM_MAX,
3905 data, data_len,
3906 wlan_hdd_extscan_config_policy)) {
3907 hddLog(LOGE, FL("Invalid ATTR"));
3908 return -EINVAL;
3909 }
3910
3911 request = vos_mem_malloc(sizeof(*request));
3912 if (!request) {
3913 hddLog(LOGE, FL("vos_mem_malloc failed"));
3914 return -ENOMEM;
3915 }
3916
3917 /* Parse and fetch request Id */
3918 if (!tb[PARAM_REQUEST_ID]) {
3919 hddLog(LOGE, FL("attr request id failed"));
3920 goto fail;
3921 }
3922
3923 request->request_id = nla_get_u32(tb[PARAM_REQUEST_ID]);
3924 hddLog(LOG1, FL("Request Id %d"), request->request_id);
3925
3926 /* Parse and fetch lost SSID sample size */
3927 if (!tb[PARAMS_LOST_SSID_SAMPLE_SIZE]) {
3928 hddLog(LOGE, FL("attr number of Ssid failed"));
3929 goto fail;
3930 }
3931 request->lost_ssid_sample_size =
3932 nla_get_u32(tb[PARAMS_LOST_SSID_SAMPLE_SIZE]);
3933 hddLog(LOG1, FL("Lost SSID Sample Size %d"),
3934 request->lost_ssid_sample_size);
3935
3936 /* Parse and fetch number of hotlist SSID */
3937 if (!tb[PARAMS_NUM_SSID]) {
3938 hddLog(LOGE, FL("attr number of Ssid failed"));
3939 goto fail;
3940 }
3941 request->ssid_count = nla_get_u32(tb[PARAMS_NUM_SSID]);
3942 hddLog(LOG1, FL("Number of SSID %d"), request->ssid_count);
3943
3944 request->session_id = adapter->sessionId;
3945 hddLog(LOG1, FL("Session Id (%d)"), request->session_id);
3946
3947 i = 0;
3948 nla_for_each_nested(ssids, tb[THRESHOLD_PARAM], rem) {
3949 if (i >= WLAN_EXTSCAN_MAX_HOTLIST_SSIDS) {
3950 hddLog(LOGE,
3951 FL("Too Many SSIDs, %d exceeds %d"),
3952 i, WLAN_EXTSCAN_MAX_HOTLIST_SSIDS);
3953 break;
3954 }
3955 if (nla_parse(tb2, PARAM_MAX,
3956 nla_data(ssids), nla_len(ssids),
3957 wlan_hdd_extscan_config_policy)) {
3958 hddLog(LOGE, FL("nla_parse failed"));
3959 goto fail;
3960 }
3961
3962 /* Parse and fetch SSID */
3963 if (!tb2[PARAM_SSID]) {
3964 hddLog(LOGE, FL("attr ssid failed"));
3965 goto fail;
3966 }
3967 nla_memcpy(ssid_string,
3968 tb2[PARAM_SSID],
3969 sizeof(ssid_string));
3970 hddLog(LOG1, FL("SSID %s"),
3971 ssid_string);
3972 ssid_len = strlen(ssid_string);
3973 memcpy(request->ssid[i].ssid.ssId, ssid_string, ssid_len);
3974 request->ssid[i].ssid.length = ssid_len;
3975 request->ssid[i].ssid.ssId[ssid_len] = '\0';
3976 hddLog(LOG1, FL("After copying SSID %s"),
3977 request->ssid[i].ssid.ssId);
3978 hddLog(LOG1, FL("After copying length: %d"),
3979 ssid_len);
3980
3981 /* Parse and fetch low RSSI */
3982 if (!tb2[PARAM_BAND]) {
3983 hddLog(LOGE, FL("attr band failed"));
3984 goto fail;
3985 }
3986 request->ssid[i].band = nla_get_u8(tb2[PARAM_BAND]);
3987 hddLog(LOG1, FL("band %d"), request->ssid[i].band);
3988
3989 /* Parse and fetch low RSSI */
3990 if (!tb2[PARAM_RSSI_LOW]) {
3991 hddLog(LOGE, FL("attr low RSSI failed"));
3992 goto fail;
3993 }
3994 request->ssid[i].rssi_low = nla_get_s32(tb2[PARAM_RSSI_LOW]);
3995 hddLog(LOG1, FL("RSSI low %d"), request->ssid[i].rssi_low);
3996
3997 /* Parse and fetch high RSSI */
3998 if (!tb2[PARAM_RSSI_HIGH]) {
3999 hddLog(LOGE, FL("attr high RSSI failed"));
4000 goto fail;
4001 }
4002 request->ssid[i].rssi_high = nla_get_u32(tb2[PARAM_RSSI_HIGH]);
4003 hddLog(LOG1, FL("RSSI high %d"), request->ssid[i].rssi_high);
4004 i++;
4005 }
4006
4007 context = &hdd_ctx->ext_scan_context;
4008 spin_lock(&hdd_context_lock);
4009 INIT_COMPLETION(context->response_event);
4010 context->request_id = request_id = request->request_id;
4011 spin_unlock(&hdd_context_lock);
4012
4013 status = sme_set_ssid_hotlist(hdd_ctx->hHal, request);
4014 if (!HAL_STATUS_SUCCESS(status)) {
4015 hddLog(LOGE,
4016 FL("sme_set_ssid_hotlist failed(err=%d)"), status);
4017 goto fail;
4018 }
4019
4020 vos_mem_free(request);
4021
4022 /* request was sent -- wait for the response */
4023 rc = wait_for_completion_timeout(&context->response_event,
4024 msecs_to_jiffies
4025 (WLAN_WAIT_TIME_EXTSCAN));
4026 if (!rc) {
4027 hddLog(LOGE, FL("sme_set_ssid_hotlist timed out"));
4028 retval = -ETIMEDOUT;
4029 } else {
4030 spin_lock(&hdd_context_lock);
4031 if (context->request_id == request_id)
4032 retval = context->response_status;
4033 else
4034 retval = -EINVAL;
4035 spin_unlock(&hdd_context_lock);
4036 }
4037
4038 return retval;
4039
4040fail:
4041 vos_mem_free(request);
4042 return -EINVAL;
4043}
4044
4045/*
4046 * done with short names for the global vendor params
4047 * used by wlan_hdd_cfg80211_extscan_set_ssid_hotlist()
4048 */
4049#undef PARAM_MAX
4050#undef PARAM_REQUEST_ID
4051#undef PARAMS_NUM_SSID
4052#undef THRESHOLD_PARAM
4053#undef PARAM_SSID
4054#undef PARAM_BAND
4055#undef PARAM_RSSI_LOW
4056#undef PARAM_RSSI_HIGH
4057
4058static int wlan_hdd_cfg80211_extscan_set_ssid_hotlist(struct wiphy *wiphy,
4059 struct wireless_dev *wdev,
4060 const void *data, int dataLen)
4061{
4062 int ret = 0;
4063
4064 vos_ssr_protect(__func__);
4065 ret = __wlan_hdd_cfg80211_extscan_set_ssid_hotlist(wiphy, wdev, data,
4066 dataLen);
4067 vos_ssr_unprotect(__func__);
4068
4069 return ret;
4070}
4071
4072static int
4073__wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4074 struct wireless_dev *wdev,
4075 const void *data,
4076 int data_len)
4077{
4078 tSirEXTScanResetSsidHotlistReqParams request;
4079 struct net_device *dev = wdev->netdev;
4080 hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
4081 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
4082 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4083 struct hdd_ext_scan_context *context;
4084 uint32_t request_id;
4085 eHalStatus status;
4086 int retval;
4087 unsigned long rc;
4088
4089 ENTER();
4090
4091 if (VOS_FTM_MODE == hdd_get_conparam()) {
4092 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4093 return -EINVAL;
4094 }
4095
4096 retval = wlan_hdd_validate_context(hdd_ctx);
4097 if (0 != retval) {
4098 hddLog(LOGE, FL("HDD context is not valid"));
4099 return -EINVAL;
4100 }
4101
4102 /* check the EXTScan Capability */
4103 if ( (TRUE != hdd_ctx->cfg_ini->fEnableEXTScan) ||
4104 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4105 {
4106 hddLog(LOGE,
4107 FL("EXTScan not enabled/supported by Firmware"));
4108 return -EINVAL;
4109 }
4110
4111 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4112 data, data_len,
4113 wlan_hdd_extscan_config_policy)) {
4114 hddLog(LOGE, FL("Invalid ATTR"));
4115 return -EINVAL;
4116 }
4117
4118 /* Parse and fetch request Id */
4119 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4120 hddLog(LOGE, FL("attr request id failed"));
4121 return -EINVAL;
4122 }
4123
4124 request.requestId = nla_get_u32(
4125 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4126 request.sessionId = adapter->sessionId;
4127 hddLog(LOG1, FL("Request Id %d Session Id %d"), request.requestId,
4128 request.sessionId);
4129
4130 context = &hdd_ctx->ext_scan_context;
4131 spin_lock(&hdd_context_lock);
4132 INIT_COMPLETION(context->response_event);
4133 context->request_id = request_id = request.requestId;
4134 spin_unlock(&hdd_context_lock);
4135
4136 status = sme_reset_ssid_hotlist(hdd_ctx->hHal, &request);
4137 if (!HAL_STATUS_SUCCESS(status)) {
4138 hddLog(LOGE,
4139 FL("sme_reset_ssid_hotlist failed(err=%d)"), status);
4140 return -EINVAL;
4141 }
4142
4143 /* request was sent -- wait for the response */
4144 rc = wait_for_completion_timeout(&context->response_event,
4145 msecs_to_jiffies
4146 (WLAN_WAIT_TIME_EXTSCAN));
4147 if (!rc) {
4148 hddLog(LOGE, FL("sme_reset_ssid_hotlist timed out"));
4149 retval = -ETIMEDOUT;
4150 } else {
4151 spin_lock(&hdd_context_lock);
4152 if (context->request_id == request_id)
4153 retval = context->response_status;
4154 else
4155 retval = -EINVAL;
4156 spin_unlock(&hdd_context_lock);
4157 }
4158
4159 return retval;
4160}
4161
4162static int
4163wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(struct wiphy *wiphy,
4164 struct wireless_dev *wdev,
4165 const void *data,
4166 int data_len)
4167{
4168 int ret;
4169
4170 vos_ssr_protect(__func__);
4171 ret = __wlan_hdd_cfg80211_extscan_reset_ssid_hotlist(wiphy, wdev,
4172 data, data_len);
4173 vos_ssr_unprotect(__func__);
4174
4175 return ret;
4176}
4177
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304178static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304179 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304180 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304181{
4182 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4183 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4184 tANI_U8 numChannels = 0;
4185 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304186 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304187 tWifiBand wifiBand;
4188 eHalStatus status;
4189 struct sk_buff *replySkb;
4190 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304191 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304192
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304193 ENTER();
4194
Dino Mycle6fb96c12014-06-10 11:52:40 +05304195 status = wlan_hdd_validate_context(pHddCtx);
4196 if (0 != status)
4197 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304198 return -EINVAL;
4199 }
Dino Myclee8843b32014-07-04 14:21:45 +05304200
Dino Mycle6fb96c12014-06-10 11:52:40 +05304201 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4202 data, dataLen,
4203 wlan_hdd_extscan_config_policy)) {
4204 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4205 return -EINVAL;
4206 }
4207
4208 /* Parse and fetch request Id */
4209 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4210 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4211 return -EINVAL;
4212 }
4213 requestId = nla_get_u32(
4214 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4215 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4216
4217 /* Parse and fetch wifi band */
4218 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4219 {
4220 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4221 return -EINVAL;
4222 }
4223 wifiBand = nla_get_u32(
4224 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4225 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4226
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304227 /* Parse and fetch max channels */
4228 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4229 {
4230 hddLog(LOGE, FL("attr max channels failed"));
4231 return -EINVAL;
4232 }
4233 maxChannels = nla_get_u32(
4234 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4235 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4236
Dino Mycle6fb96c12014-06-10 11:52:40 +05304237 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
4238 wifiBand, ChannelList,
4239 &numChannels);
4240 if (eHAL_STATUS_SUCCESS != status) {
4241 hddLog(VOS_TRACE_LEVEL_ERROR,
4242 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4243 return -EINVAL;
4244 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304245
4246 numChannels = VOS_MIN(numChannels, maxChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304247 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304248
Dino Mycle6fb96c12014-06-10 11:52:40 +05304249 for (i = 0; i < numChannels; i++)
4250 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
4251
4252 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4253 sizeof(u32) * numChannels +
4254 NLMSG_HDRLEN);
4255
4256 if (!replySkb) {
4257 hddLog(VOS_TRACE_LEVEL_ERROR,
4258 FL("valid channels: buffer alloc fail"));
4259 return -EINVAL;
4260 }
4261 if (nla_put_u32(replySkb,
4262 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
4263 numChannels) ||
4264 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
4265 sizeof(u32) * numChannels, ChannelList)) {
4266
4267 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4268 kfree_skb(replySkb);
4269 return -EINVAL;
4270 }
4271
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304272 ret = cfg80211_vendor_cmd_reply(replySkb);
4273
4274 EXIT();
4275 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304276}
4277
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304278static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4279 struct wireless_dev *wdev,
4280 const void *data, int dataLen)
4281{
4282 int ret = 0;
4283
4284 vos_ssr_protect(__func__);
4285 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4286 dataLen);
4287 vos_ssr_unprotect(__func__);
4288
4289 return ret;
4290}
4291
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304292static int hdd_extscan_start_fill_bucket_channel_spec(
4293 hdd_context_t *pHddCtx,
4294 tpSirEXTScanStartReqParams pReqMsg,
4295 struct nlattr **tb)
4296{
4297 struct nlattr *bucket[
4298 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4299 struct nlattr *channel[
4300 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4301 struct nlattr *buckets;
4302 struct nlattr *channels;
4303 int rem1, rem2;
4304 eHalStatus status;
4305 tANI_U8 bktIndex, j, numChannels;
4306 tANI_U32 chanList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4307 tANI_U32 passive_max_chn_time, active_max_chn_time;
4308
4309 bktIndex = 0;
4310
4311 nla_for_each_nested(buckets,
4312 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4313 if (nla_parse(bucket,
4314 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4315 nla_data(buckets), nla_len(buckets), NULL)) {
4316 hddLog(LOGE, FL("nla_parse failed"));
4317 return -EINVAL;
4318 }
4319
4320 /* Parse and fetch bucket spec */
4321 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4322 hddLog(LOGE, FL("attr bucket index failed"));
4323 return -EINVAL;
4324 }
4325 pReqMsg->buckets[bktIndex].bucket = nla_get_u8(
4326 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4327 hddLog(LOG1, FL("Bucket spec Index %d"),
4328 pReqMsg->buckets[bktIndex].bucket);
4329
4330 /* Parse and fetch wifi band */
4331 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4332 hddLog(LOGE, FL("attr wifi band failed"));
4333 return -EINVAL;
4334 }
4335 pReqMsg->buckets[bktIndex].band = nla_get_u8(
4336 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4337 hddLog(LOG1, FL("Wifi band %d"),
4338 pReqMsg->buckets[bktIndex].band);
4339
4340 /* Parse and fetch period */
4341 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4342 hddLog(LOGE, FL("attr period failed"));
4343 return -EINVAL;
4344 }
4345 pReqMsg->buckets[bktIndex].period = nla_get_u32(
4346 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4347 hddLog(LOG1, FL("period %d"),
4348 pReqMsg->buckets[bktIndex].period);
4349
4350 /* Parse and fetch report events */
4351 if (!bucket[
4352 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4353 hddLog(LOGE, FL("attr report events failed"));
4354 return -EINVAL;
4355 }
4356 pReqMsg->buckets[bktIndex].reportEvents = nla_get_u8(
4357 bucket[
4358 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4359 hddLog(LOG1, FL("report events %d"),
4360 pReqMsg->buckets[bktIndex].reportEvents);
4361
4362 /* Parse and fetch max period */
4363 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]) {
4364 hddLog(LOGE, FL("attr max period failed"));
4365 return -EINVAL;
4366 }
4367 pReqMsg->buckets[bktIndex].max_period = nla_get_u32(
4368 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_MAX_PERIOD]);
4369 hddLog(LOG1, FL("max period %u"),
4370 pReqMsg->buckets[bktIndex].max_period);
4371
4372 /* Parse and fetch exponent */
4373 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]) {
4374 hddLog(LOGE, FL("attr exponent failed"));
4375 return -EINVAL;
4376 }
4377 pReqMsg->buckets[bktIndex].exponent = nla_get_u32(
4378 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_EXPONENT]);
4379 hddLog(LOG1, FL("exponent %u"),
4380 pReqMsg->buckets[bktIndex].exponent);
4381
4382 /* Parse and fetch step count */
4383 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]) {
4384 hddLog(LOGE, FL("attr step count failed"));
4385 return -EINVAL;
4386 }
4387 pReqMsg->buckets[bktIndex].step_count = nla_get_u32(
4388 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_STEP_COUNT]);
4389 hddLog(LOG1, FL("Step count %u"),
4390 pReqMsg->buckets[bktIndex].step_count);
4391
4392 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &passive_max_chn_time);
4393 ccmCfgGetInt(pHddCtx->hHal, WNI_CFG_PASSIVE_MAXIMUM_CHANNEL_TIME, &active_max_chn_time);
4394
4395 /* Framework shall pass the channel list if the input WiFi band is
4396 * WIFI_BAND_UNSPECIFIED.
4397 * If the input WiFi band is specified (any value other than
4398 * WIFI_BAND_UNSPECIFIED) then driver populates the channel list
4399 */
4400 if (pReqMsg->buckets[bktIndex].band != WIFI_BAND_UNSPECIFIED) {
4401 numChannels = 0;
4402 hddLog(LOG1, "WiFi band is specified, driver to fill channel list");
4403 status = sme_GetValidChannelsByBand(pHddCtx->hHal,
4404 pReqMsg->buckets[bktIndex].band,
4405 chanList, &numChannels);
4406 if (!HAL_STATUS_SUCCESS(status)) {
4407 hddLog(LOGE,
4408 FL("sme_GetValidChannelsByBand failed (err=%d)"),
4409 status);
4410 return -EINVAL;
4411 }
4412
4413 pReqMsg->buckets[bktIndex].numChannels =
4414 VOS_MIN(numChannels, WLAN_EXTSCAN_MAX_CHANNELS);
4415 hddLog(LOG1, FL("Num channels %d"),
4416 pReqMsg->buckets[bktIndex].numChannels);
4417
4418 for (j = 0; j < pReqMsg->buckets[bktIndex].numChannels;
4419 j++) {
4420 pReqMsg->buckets[bktIndex].channels[j].channel =
4421 chanList[j];
4422 pReqMsg->buckets[bktIndex].channels[j].
4423 chnlClass = 0;
4424 if (CSR_IS_CHANNEL_DFS(
4425 vos_freq_to_chan(chanList[j]))) {
4426 pReqMsg->buckets[bktIndex].channels[j].
4427 passive = 1;
4428 pReqMsg->buckets[bktIndex].channels[j].
4429 dwellTimeMs = passive_max_chn_time;
4430 } else {
4431 pReqMsg->buckets[bktIndex].channels[j].
4432 passive = 0;
4433 pReqMsg->buckets[bktIndex].channels[j].
4434 dwellTimeMs = active_max_chn_time;
4435 }
4436
4437 hddLog(LOG1,
4438 "Channel %u Passive %u Dwell time %u ms",
4439 pReqMsg->buckets[bktIndex].channels[j].channel,
4440 pReqMsg->buckets[bktIndex].channels[j].passive,
4441 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4442 }
4443
4444 bktIndex++;
4445 continue;
4446 }
4447
4448 /* Parse and fetch number of channels */
4449 if (!bucket[
4450 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]) {
4451 hddLog(LOGE, FL("attr num channels failed"));
4452 return -EINVAL;
4453 }
4454
4455 pReqMsg->buckets[bktIndex].numChannels =
4456 nla_get_u32(bucket[
4457 QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4458 hddLog(LOG1, FL("num channels %d"),
4459 pReqMsg->buckets[bktIndex].numChannels);
4460
4461 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4462 hddLog(LOGE, FL("attr channel spec failed"));
4463 return -EINVAL;
4464 }
4465
4466 j = 0;
4467 nla_for_each_nested(channels,
4468 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4469 if (nla_parse(channel,
4470 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4471 nla_data(channels), nla_len(channels),
4472 wlan_hdd_extscan_config_policy)) {
4473 hddLog(LOGE, FL("nla_parse failed"));
4474 return -EINVAL;
4475 }
4476
4477 /* Parse and fetch channel */
4478 if (!channel[
4479 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4480 hddLog(LOGE, FL("attr channel failed"));
4481 return -EINVAL;
4482 }
4483 pReqMsg->buckets[bktIndex].channels[j].channel =
4484 nla_get_u32(channel[
4485 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4486 hddLog(LOG1, FL("channel %u"),
4487 pReqMsg->buckets[bktIndex].channels[j].channel);
4488
4489 /* Parse and fetch dwell time */
4490 if (!channel[
4491 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4492 hddLog(LOGE, FL("attr dwelltime failed"));
4493 return -EINVAL;
4494 }
4495 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs =
4496 nla_get_u32(channel[
4497 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4498
4499 hddLog(LOG1, FL("Dwell time (%u ms)"),
4500 pReqMsg->buckets[bktIndex].channels[j].dwellTimeMs);
4501
4502
4503 /* Parse and fetch channel spec passive */
4504 if (!channel[
4505 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4506 hddLog(LOGE,
4507 FL("attr channel spec passive failed"));
4508 return -EINVAL;
4509 }
4510 pReqMsg->buckets[bktIndex].channels[j].passive =
4511 nla_get_u8(channel[
4512 QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4513 hddLog(LOG1, FL("Chnl spec passive %u"),
4514 pReqMsg->buckets[bktIndex].channels[j].passive);
4515
4516 j++;
4517 }
4518
4519 bktIndex++;
4520 }
4521
4522 return 0;
4523}
4524
4525
4526/*
4527 * define short names for the global vendor params
4528 * used by wlan_hdd_cfg80211_extscan_start()
4529 */
4530#define PARAM_MAX \
4531QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX
4532#define PARAM_REQUEST_ID \
4533QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
4534#define PARAM_BASE_PERIOD \
4535QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD
4536#define PARAM_MAX_AP_PER_SCAN \
4537QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN
4538#define PARAM_RPT_THRHLD_PERCENT \
4539QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_PERCENT
4540#define PARAM_RPT_THRHLD_NUM_SCANS \
4541QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD_NUM_SCANS
4542#define PARAM_NUM_BUCKETS \
4543QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS
4544
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304545static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304546 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304547 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304548{
Dino Myclee8843b32014-07-04 14:21:45 +05304549 tpSirEXTScanStartReqParams pReqMsg = NULL;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304550 struct net_device *dev = wdev->netdev;
4551 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4552 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4553 struct nlattr *tb[PARAM_MAX + 1];
4554 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304555 eHalStatus status;
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304556 tANI_U32 request_id;
4557 struct hdd_ext_scan_context *context;
4558 unsigned long rc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304559
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304560 ENTER();
4561
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304562 if (VOS_FTM_MODE == hdd_get_conparam()) {
4563 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4564 return -EINVAL;
4565 }
4566
Dino Mycle6fb96c12014-06-10 11:52:40 +05304567 status = wlan_hdd_validate_context(pHddCtx);
4568 if (0 != status)
4569 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304570 return -EINVAL;
4571 }
Dino Myclee8843b32014-07-04 14:21:45 +05304572 /* check the EXTScan Capability */
4573 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4574 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4575 {
4576 hddLog(VOS_TRACE_LEVEL_ERROR,
4577 FL("EXTScan not enabled/supported by Firmware"));
4578 return -EINVAL;
4579 }
4580
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304581 if (nla_parse(tb, PARAM_MAX,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304582 data, dataLen,
4583 wlan_hdd_extscan_config_policy)) {
4584 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4585 return -EINVAL;
4586 }
4587
4588 /* Parse and fetch request Id */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304589 if (!tb[PARAM_REQUEST_ID]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304590 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4591 return -EINVAL;
4592 }
4593
Dino Myclee8843b32014-07-04 14:21:45 +05304594 pReqMsg = (tpSirEXTScanStartReqParams)
4595 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304596 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304597 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4598 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304599 }
4600
4601 pReqMsg->requestId = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304602 tb[PARAM_REQUEST_ID]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304603 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4604
4605 pReqMsg->sessionId = pAdapter->sessionId;
4606 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4607
4608 /* Parse and fetch base period */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304609 if (!tb[PARAM_BASE_PERIOD]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304610 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4611 goto fail;
4612 }
4613 pReqMsg->basePeriod = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304614 tb[PARAM_BASE_PERIOD]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304615 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4616 pReqMsg->basePeriod);
4617
4618 /* Parse and fetch max AP per scan */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304619 if (!tb[PARAM_MAX_AP_PER_SCAN]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304620 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4621 goto fail;
4622 }
4623 pReqMsg->maxAPperScan = nla_get_u32(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304624 tb[PARAM_MAX_AP_PER_SCAN]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304625 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4626 pReqMsg->maxAPperScan);
4627
4628 /* Parse and fetch report threshold */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304629 if (!tb[PARAM_RPT_THRHLD_PERCENT]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304630 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4631 goto fail;
4632 }
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304633 pReqMsg->reportThresholdPercent = nla_get_u8(
4634 tb[PARAM_RPT_THRHLD_PERCENT]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304635 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304636 pReqMsg->reportThresholdPercent);
4637
4638 /* Parse and fetch report threshold num scans */
4639 if (!tb[PARAM_RPT_THRHLD_NUM_SCANS]) {
4640 hddLog(LOGE, FL("attr report_threshold num scans failed"));
4641 goto fail;
4642 }
4643 pReqMsg->reportThresholdNumScans = nla_get_u8(
4644 tb[PARAM_RPT_THRHLD_NUM_SCANS]);
4645 hddLog(LOG1, FL("Report Threshold num scans %d"),
4646 pReqMsg->reportThresholdNumScans);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304647
4648 /* Parse and fetch number of buckets */
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304649 if (!tb[PARAM_NUM_BUCKETS]) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304650 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4651 goto fail;
4652 }
4653 pReqMsg->numBuckets = nla_get_u8(
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304654 tb[PARAM_NUM_BUCKETS]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304655 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4656 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4657 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4658 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4659 }
4660 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4661 pReqMsg->numBuckets);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304662
Dino Mycle6fb96c12014-06-10 11:52:40 +05304663 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4664 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4665 goto fail;
4666 }
4667
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304668 pReqMsg->homeAwayTime = pHddCtx->cfg_ini->nRestTimeConc;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304669
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304670 if (hdd_extscan_start_fill_bucket_channel_spec(pHddCtx, pReqMsg, tb))
4671 goto fail;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304672
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304673 context = &pHddCtx->ext_scan_context;
4674 spin_lock(&hdd_context_lock);
4675 INIT_COMPLETION(context->response_event);
4676 context->request_id = request_id = pReqMsg->requestId;
4677 spin_unlock(&hdd_context_lock);
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304678
Dino Mycle6fb96c12014-06-10 11:52:40 +05304679 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4680 if (!HAL_STATUS_SUCCESS(status)) {
4681 hddLog(VOS_TRACE_LEVEL_ERROR,
4682 FL("sme_EXTScanStart failed(err=%d)"), status);
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304683 goto fail;
4684 }
4685
4686 /* request was sent -- wait for the response */
4687 rc = wait_for_completion_timeout(&context->response_event,
4688 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4689
4690 if (!rc) {
4691 hddLog(LOGE, FL("sme_ExtScanStart timed out"));
4692 retval = -ETIMEDOUT;
4693 } else {
4694 spin_lock(&hdd_context_lock);
4695 if (context->request_id == request_id)
4696 retval = context->response_status;
4697 else
4698 retval = -EINVAL;
4699 spin_unlock(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304700 }
4701
Dino Myclee8843b32014-07-04 14:21:45 +05304702 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304703 EXIT();
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304704 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304705
4706fail:
4707 vos_mem_free(pReqMsg);
4708 return -EINVAL;
4709}
4710
Padma, Santhosh Kumar7b9190d2015-08-17 17:45:29 +05304711/*
4712 * done with short names for the global vendor params
4713 * used by wlan_hdd_cfg80211_extscan_start()
4714 */
4715#undef PARAM_MAX
4716#undef PARAM_REQUEST_ID
4717#undef PARAM_BASE_PERIOD
4718#undef PARAMS_MAX_AP_PER_SCAN
4719#undef PARAMS_RPT_THRHLD_PERCENT
4720#undef PARAMS_RPT_THRHLD_NUM_SCANS
4721#undef PARAMS_NUM_BUCKETS
4722
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304723static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4724 struct wireless_dev *wdev,
4725 const void *data, int dataLen)
4726{
4727 int ret = 0;
4728
4729 vos_ssr_protect(__func__);
4730 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4731 vos_ssr_unprotect(__func__);
4732
4733 return ret;
4734}
4735
4736static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304737 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304738 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304739{
Dino Myclee8843b32014-07-04 14:21:45 +05304740 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304741 struct net_device *dev = wdev->netdev;
4742 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4743 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4744 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4745 eHalStatus status;
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304746 int retval;
4747 unsigned long rc;
4748 struct hdd_ext_scan_context *context;
4749 tANI_U32 request_id;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304750
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304751 ENTER();
4752
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304753 if (VOS_FTM_MODE == hdd_get_conparam()) {
4754 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4755 return -EINVAL;
4756 }
4757
Dino Mycle6fb96c12014-06-10 11:52:40 +05304758 status = wlan_hdd_validate_context(pHddCtx);
4759 if (0 != status)
4760 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304761 return -EINVAL;
4762 }
Dino Myclee8843b32014-07-04 14:21:45 +05304763 /* check the EXTScan Capability */
4764 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4765 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4766 {
4767 hddLog(VOS_TRACE_LEVEL_ERROR,
4768 FL("EXTScan not enabled/supported by Firmware"));
4769 return -EINVAL;
4770 }
4771
Dino Mycle6fb96c12014-06-10 11:52:40 +05304772 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4773 data, dataLen,
4774 wlan_hdd_extscan_config_policy)) {
4775 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4776 return -EINVAL;
4777 }
4778
4779 /* Parse and fetch request Id */
4780 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4781 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4782 return -EINVAL;
4783 }
4784
Dino Myclee8843b32014-07-04 14:21:45 +05304785 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304786 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304787 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304788
Dino Myclee8843b32014-07-04 14:21:45 +05304789 reqMsg.sessionId = pAdapter->sessionId;
4790 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304791
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304792 context = &pHddCtx->ext_scan_context;
4793 spin_lock(&hdd_context_lock);
4794 INIT_COMPLETION(context->response_event);
4795 context->request_id = request_id = reqMsg.sessionId;
4796 spin_unlock(&hdd_context_lock);
4797
Dino Myclee8843b32014-07-04 14:21:45 +05304798 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304799 if (!HAL_STATUS_SUCCESS(status)) {
4800 hddLog(VOS_TRACE_LEVEL_ERROR,
4801 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304802 return -EINVAL;
4803 }
4804
Padma, Santhosh Kumar57cff7f2015-08-17 18:33:14 +05304805 /* request was sent -- wait for the response */
4806 rc = wait_for_completion_timeout(&context->response_event,
4807 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4808
4809 if (!rc) {
4810 hddLog(LOGE, FL("sme_ExtScanStop timed out"));
4811 retval = -ETIMEDOUT;
4812 } else {
4813 spin_lock(&hdd_context_lock);
4814 if (context->request_id == request_id)
4815 retval = context->response_status;
4816 else
4817 retval = -EINVAL;
4818 spin_unlock(&hdd_context_lock);
4819 }
4820
4821 return retval;
4822
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304823 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304824 return 0;
4825}
4826
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304827static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4828 struct wireless_dev *wdev,
4829 const void *data, int dataLen)
4830{
4831 int ret = 0;
4832
4833 vos_ssr_protect(__func__);
4834 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4835 vos_ssr_unprotect(__func__);
4836
4837 return ret;
4838}
4839
4840static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304841 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304842 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304843{
Dino Myclee8843b32014-07-04 14:21:45 +05304844 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304845 struct net_device *dev = wdev->netdev;
4846 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4847 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4848 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4849 eHalStatus status;
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304850 struct hdd_ext_scan_context *context;
4851 tANI_U32 request_id;
4852 unsigned long rc;
4853 int retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304854
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304855 ENTER();
4856
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304857 if (VOS_FTM_MODE == hdd_get_conparam()) {
4858 hddLog(LOGE, FL("Command not allowed in FTM mode"));
4859 return -EINVAL;
4860 }
4861
Dino Mycle6fb96c12014-06-10 11:52:40 +05304862 status = wlan_hdd_validate_context(pHddCtx);
4863 if (0 != status)
4864 {
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304865 hddLog(LOGE, FL("HDD context is not valid"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304866 return -EINVAL;
4867 }
Dino Myclee8843b32014-07-04 14:21:45 +05304868 /* check the EXTScan Capability */
4869 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4870 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4871 {
4872 hddLog(VOS_TRACE_LEVEL_ERROR,
4873 FL("EXTScan not enabled/supported by Firmware"));
4874 return -EINVAL;
4875 }
4876
Dino Mycle6fb96c12014-06-10 11:52:40 +05304877 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4878 data, dataLen,
4879 wlan_hdd_extscan_config_policy)) {
4880 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4881 return -EINVAL;
4882 }
4883
4884 /* Parse and fetch request Id */
4885 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4886 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4887 return -EINVAL;
4888 }
4889
Dino Myclee8843b32014-07-04 14:21:45 +05304890 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304891 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304892 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304893
Dino Myclee8843b32014-07-04 14:21:45 +05304894 reqMsg.sessionId = pAdapter->sessionId;
4895 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304896
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304897 context = &pHddCtx->ext_scan_context;
4898 spin_lock(&hdd_context_lock);
4899 INIT_COMPLETION(context->response_event);
4900 context->request_id = request_id = reqMsg.requestId;
4901 spin_unlock(&hdd_context_lock);
4902
Dino Myclee8843b32014-07-04 14:21:45 +05304903 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304904 if (!HAL_STATUS_SUCCESS(status)) {
4905 hddLog(VOS_TRACE_LEVEL_ERROR,
4906 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304907 return -EINVAL;
4908 }
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304909
4910 /* request was sent -- wait for the response */
4911 rc = wait_for_completion_timeout(&context->response_event,
4912 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
4913 if (!rc) {
4914 hddLog(LOGE, FL("sme_ResetBssHotlist timed out"));
4915 retval = -ETIMEDOUT;
4916 } else {
4917 spin_lock(&hdd_context_lock);
4918 if (context->request_id == request_id)
4919 retval = context->response_status;
4920 else
4921 retval = -EINVAL;
4922 spin_unlock(&hdd_context_lock);
4923 }
4924
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304925 EXIT();
Padma, Santhosh Kumar04a3bab2015-08-20 13:09:35 +05304926 return retval;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304927}
4928
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304929static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4930 struct wireless_dev *wdev,
4931 const void *data, int dataLen)
4932{
4933 int ret = 0;
4934
4935 vos_ssr_protect(__func__);
4936 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4937 vos_ssr_unprotect(__func__);
4938
4939 return ret;
4940}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304941#endif /* WLAN_FEATURE_EXTSCAN */
4942
Atul Mittal115287b2014-07-08 13:26:33 +05304943/*EXT TDLS*/
4944static const struct nla_policy
4945wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4946{
4947 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4948 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4949 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4950 {.type = NLA_S32 },
4951 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4952 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4953
4954};
4955
4956static const struct nla_policy
4957wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4958{
4959 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4960
4961};
4962
4963static const struct nla_policy
4964wlan_hdd_tdls_config_state_change_policy[
4965 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4966{
4967 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4968 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4969 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304970 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4971 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4972 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304973
4974};
4975
4976static const struct nla_policy
4977wlan_hdd_tdls_config_get_status_policy[
4978 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4979{
4980 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4981 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4982 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304983 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4984 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4985 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304986
4987};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304988
4989static const struct nla_policy
4990wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4991{
4992 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
4993};
4994
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304995static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304996 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304997 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304998 int data_len)
4999{
5000
5001 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5002 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
5003
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305004 ENTER();
5005
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305006 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305007 return -EINVAL;
5008 }
5009 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05305010 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305011 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05305012 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305013 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05305014 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305015 return -ENOTSUPP;
5016 }
5017
5018 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
5019 data, data_len, wlan_hdd_mac_config)) {
5020 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5021 return -EINVAL;
5022 }
5023
5024 /* Parse and fetch mac address */
5025 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
5026 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5027 return -EINVAL;
5028 }
5029
5030 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
5031 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5032 VOS_MAC_ADDR_LAST_3_BYTES);
5033
Siddharth Bhal76972212014-10-15 16:22:51 +05305034 pHddCtx->spoofMacAddr.isEnabled = TRUE;
5035
5036 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305037 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
5038 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05305039 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
5040 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
5041 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
5042 {
5043 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
5044 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
5045 VOS_MAC_ADDRESS_LEN);
5046 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305047 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305048
Siddharth Bhal76972212014-10-15 16:22:51 +05305049 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
5050 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305051 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
5052 }
5053
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305054 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305055 return 0;
5056}
5057
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305058static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
5059 struct wireless_dev *wdev,
5060 const void *data,
5061 int data_len)
5062{
5063 int ret = 0;
5064
5065 vos_ssr_protect(__func__);
5066 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
5067 vos_ssr_unprotect(__func__);
5068
5069 return ret;
5070}
5071
5072static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305073 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305074 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305075 int data_len)
5076{
5077 u8 peer[6] = {0};
5078 struct net_device *dev = wdev->netdev;
5079 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5080 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5081 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
5082 eHalStatus ret;
5083 tANI_S32 state;
5084 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305085 tANI_S32 global_operating_class = 0;
5086 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05305087 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305088 int retVal;
5089
5090 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305091
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305092 if (!pAdapter) {
5093 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5094 return -EINVAL;
5095 }
5096
Atul Mittal115287b2014-07-08 13:26:33 +05305097 ret = wlan_hdd_validate_context(pHddCtx);
5098 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305099 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305100 return -EINVAL;
5101 }
5102 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305103 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305104 return -ENOTSUPP;
5105 }
5106 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
5107 data, data_len,
5108 wlan_hdd_tdls_config_get_status_policy)) {
5109 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5110 return -EINVAL;
5111 }
5112
5113 /* Parse and fetch mac address */
5114 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
5115 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5116 return -EINVAL;
5117 }
5118
5119 memcpy(peer, nla_data(
5120 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
5121 sizeof(peer));
5122 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5123
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05305124 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05305125
Atul Mittal115287b2014-07-08 13:26:33 +05305126 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305127 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05305128 NLMSG_HDRLEN);
5129
5130 if (!skb) {
5131 hddLog(VOS_TRACE_LEVEL_ERROR,
5132 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5133 return -EINVAL;
5134 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305135 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 +05305136 reason,
5137 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305138 global_operating_class,
5139 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05305140 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305141 if (nla_put_s32(skb,
5142 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
5143 state) ||
5144 nla_put_s32(skb,
5145 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
5146 reason) ||
5147 nla_put_s32(skb,
5148 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
5149 global_operating_class) ||
5150 nla_put_s32(skb,
5151 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
5152 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05305153
5154 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5155 goto nla_put_failure;
5156 }
5157
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305158 retVal = cfg80211_vendor_cmd_reply(skb);
5159 EXIT();
5160 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05305161
5162nla_put_failure:
5163 kfree_skb(skb);
5164 return -EINVAL;
5165}
5166
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305167static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
5168 struct wireless_dev *wdev,
5169 const void *data,
5170 int data_len)
5171{
5172 int ret = 0;
5173
5174 vos_ssr_protect(__func__);
5175 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
5176 vos_ssr_unprotect(__func__);
5177
5178 return ret;
5179}
5180
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05305181static int wlan_hdd_cfg80211_exttdls_callback(
5182#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
5183 const tANI_U8* mac,
5184#else
5185 tANI_U8* mac,
5186#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305187 tANI_S32 state,
5188 tANI_S32 reason,
5189 void *ctx)
5190{
5191 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05305192 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305193 tANI_S32 global_operating_class = 0;
5194 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305195 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05305196
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305197 ENTER();
5198
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305199 if (!pAdapter) {
5200 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5201 return -EINVAL;
5202 }
5203
5204 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05305205 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305206 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305207 return -EINVAL;
5208 }
5209
5210 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305211 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305212 return -ENOTSUPP;
5213 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05305214 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
5215#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
5216 NULL,
5217#endif
Atul Mittal115287b2014-07-08 13:26:33 +05305218 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
5219 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
5220 GFP_KERNEL);
5221
5222 if (!skb) {
5223 hddLog(VOS_TRACE_LEVEL_ERROR,
5224 FL("cfg80211_vendor_event_alloc failed"));
5225 return -EINVAL;
5226 }
5227 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305228 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
5229 reason,
5230 state,
5231 global_operating_class,
5232 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05305233 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
5234 MAC_ADDR_ARRAY(mac));
5235
Atul Mittal0a9f68d2014-10-16 15:26:38 +05305236 if (nla_put(skb,
5237 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
5238 VOS_MAC_ADDR_SIZE, mac) ||
5239 nla_put_s32(skb,
5240 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
5241 state) ||
5242 nla_put_s32(skb,
5243 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
5244 reason) ||
5245 nla_put_s32(skb,
5246 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
5247 channel) ||
5248 nla_put_s32(skb,
5249 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
5250 global_operating_class)
5251 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05305252 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
5253 goto nla_put_failure;
5254 }
5255
5256 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305257 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05305258 return (0);
5259
5260nla_put_failure:
5261 kfree_skb(skb);
5262 return -EINVAL;
5263}
5264
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305265static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305266 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305267 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305268 int data_len)
5269{
5270 u8 peer[6] = {0};
5271 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305272 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5273 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
5274 eHalStatus status;
5275 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305276 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305277 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305278
5279 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305280
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305281 if (!dev) {
5282 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5283 return -EINVAL;
5284 }
5285
5286 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5287 if (!pAdapter) {
5288 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
5289 return -EINVAL;
5290 }
5291
Atul Mittal115287b2014-07-08 13:26:33 +05305292 status = wlan_hdd_validate_context(pHddCtx);
5293 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305294 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305295 return -EINVAL;
5296 }
5297 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305298 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305299 return -ENOTSUPP;
5300 }
5301 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
5302 data, data_len,
5303 wlan_hdd_tdls_config_enable_policy)) {
5304 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5305 return -EINVAL;
5306 }
5307
5308 /* Parse and fetch mac address */
5309 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
5310 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5311 return -EINVAL;
5312 }
5313
5314 memcpy(peer, nla_data(
5315 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5316 sizeof(peer));
5317 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5318
5319 /* Parse and fetch channel */
5320 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5321 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5322 return -EINVAL;
5323 }
5324 pReqMsg.channel = nla_get_s32(
5325 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5326 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5327
5328 /* Parse and fetch global operating class */
5329 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5330 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5331 return -EINVAL;
5332 }
5333 pReqMsg.global_operating_class = nla_get_s32(
5334 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5335 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5336 pReqMsg.global_operating_class);
5337
5338 /* Parse and fetch latency ms */
5339 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5340 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5341 return -EINVAL;
5342 }
5343 pReqMsg.max_latency_ms = nla_get_s32(
5344 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5345 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5346 pReqMsg.max_latency_ms);
5347
5348 /* Parse and fetch required bandwidth kbps */
5349 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5350 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5351 return -EINVAL;
5352 }
5353
5354 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5355 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5356 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5357 pReqMsg.min_bandwidth_kbps);
5358
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305359 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305360 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305361 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305362 wlan_hdd_cfg80211_exttdls_callback);
5363
5364 EXIT();
5365 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305366}
5367
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305368static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5369 struct wireless_dev *wdev,
5370 const void *data,
5371 int data_len)
5372{
5373 int ret = 0;
5374
5375 vos_ssr_protect(__func__);
5376 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5377 vos_ssr_unprotect(__func__);
5378
5379 return ret;
5380}
5381
5382static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305383 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305384 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305385 int data_len)
5386{
5387 u8 peer[6] = {0};
5388 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305389 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5390 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5391 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305392 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305393 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305394
5395 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305396
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305397 if (!dev) {
5398 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5399 return -EINVAL;
5400 }
5401
5402 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5403 if (!pAdapter) {
5404 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5405 return -EINVAL;
5406 }
5407
Atul Mittal115287b2014-07-08 13:26:33 +05305408 status = wlan_hdd_validate_context(pHddCtx);
5409 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305410 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305411 return -EINVAL;
5412 }
5413 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305414 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305415 return -ENOTSUPP;
5416 }
5417 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5418 data, data_len,
5419 wlan_hdd_tdls_config_disable_policy)) {
5420 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5421 return -EINVAL;
5422 }
5423 /* Parse and fetch mac address */
5424 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5425 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5426 return -EINVAL;
5427 }
5428
5429 memcpy(peer, nla_data(
5430 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5431 sizeof(peer));
5432 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5433
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305434 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5435
5436 EXIT();
5437 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305438}
5439
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305440static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5441 struct wireless_dev *wdev,
5442 const void *data,
5443 int data_len)
5444{
5445 int ret = 0;
5446
5447 vos_ssr_protect(__func__);
5448 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5449 vos_ssr_unprotect(__func__);
5450
5451 return ret;
5452}
5453
Dasari Srinivas7875a302014-09-26 17:50:57 +05305454static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305455__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305456 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305457 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305458{
5459 struct net_device *dev = wdev->netdev;
5460 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5461 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5462 struct sk_buff *skb = NULL;
5463 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305464 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305465
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305466 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305467
5468 ret = wlan_hdd_validate_context(pHddCtx);
5469 if (0 != ret)
5470 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305471 return ret;
5472 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305473 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5474 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5475 fset |= WIFI_FEATURE_INFRA;
5476 }
5477
5478 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5479 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5480 fset |= WIFI_FEATURE_INFRA_5G;
5481 }
5482
5483#ifdef WLAN_FEATURE_P2P
5484 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5485 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5486 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5487 fset |= WIFI_FEATURE_P2P;
5488 }
5489#endif
5490
5491 /* Soft-AP is supported currently by default */
5492 fset |= WIFI_FEATURE_SOFT_AP;
5493
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305494 /* HOTSPOT is a supplicant feature, enable it by default */
5495 fset |= WIFI_FEATURE_HOTSPOT;
5496
Dasari Srinivas7875a302014-09-26 17:50:57 +05305497#ifdef WLAN_FEATURE_EXTSCAN
5498 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
5499 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
5500 hddLog(LOG1, FL("EXTScan is supported by firmware"));
5501 fset |= WIFI_FEATURE_EXTSCAN;
5502 }
5503#endif
5504
Dasari Srinivas7875a302014-09-26 17:50:57 +05305505 if (sme_IsFeatureSupportedByFW(NAN)) {
5506 hddLog(LOG1, FL("NAN is supported by firmware"));
5507 fset |= WIFI_FEATURE_NAN;
5508 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305509
5510 /* D2D RTT is not supported currently by default */
5511 if (sme_IsFeatureSupportedByFW(RTT)) {
5512 hddLog(LOG1, FL("RTT is supported by firmware"));
5513 fset |= WIFI_FEATURE_D2AP_RTT;
5514 }
5515
5516#ifdef FEATURE_WLAN_BATCH_SCAN
5517 if (fset & WIFI_FEATURE_EXTSCAN) {
5518 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5519 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5520 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5521 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5522 fset |= WIFI_FEATURE_BATCH_SCAN;
5523 }
5524#endif
5525
5526#ifdef FEATURE_WLAN_SCAN_PNO
5527 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5528 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5529 hddLog(LOG1, FL("PNO is supported by firmware"));
5530 fset |= WIFI_FEATURE_PNO;
5531 }
5532#endif
5533
5534 /* STA+STA is supported currently by default */
5535 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5536
5537#ifdef FEATURE_WLAN_TDLS
5538 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5539 sme_IsFeatureSupportedByFW(TDLS)) {
5540 hddLog(LOG1, FL("TDLS is supported by firmware"));
5541 fset |= WIFI_FEATURE_TDLS;
5542 }
5543
5544 /* TDLS_OFFCHANNEL is not supported currently by default */
5545#endif
5546
5547#ifdef WLAN_AP_STA_CONCURRENCY
5548 /* AP+STA concurrency is supported currently by default */
5549 fset |= WIFI_FEATURE_AP_STA;
5550#endif
5551
Mukul Sharma5add0532015-08-17 15:57:47 +05305552#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5553 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5554 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5555#endif
5556
Dasari Srinivas7875a302014-09-26 17:50:57 +05305557 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5558 NLMSG_HDRLEN);
5559
5560 if (!skb) {
5561 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5562 return -EINVAL;
5563 }
5564 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5565
5566 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5567 hddLog(LOGE, FL("nla put fail"));
5568 goto nla_put_failure;
5569 }
5570
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305571 ret = cfg80211_vendor_cmd_reply(skb);
5572 EXIT();
5573 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305574
5575nla_put_failure:
5576 kfree_skb(skb);
5577 return -EINVAL;
5578}
5579
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305580static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305581wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5582 struct wireless_dev *wdev,
5583 const void *data, int data_len)
5584{
5585 int ret = 0;
5586
5587 vos_ssr_protect(__func__);
5588 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5589 vos_ssr_unprotect(__func__);
5590
5591 return ret;
5592}
5593
5594static int
5595__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305596 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305597 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305598{
5599 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5600 uint8_t i, feature_sets, max_feature_sets;
5601 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5602 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305603 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5604 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305605
5606 ENTER();
5607
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305608 ret = wlan_hdd_validate_context(pHddCtx);
5609 if (0 != ret)
5610 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305611 return ret;
5612 }
5613
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305614 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5615 data, data_len, NULL)) {
5616 hddLog(LOGE, FL("Invalid ATTR"));
5617 return -EINVAL;
5618 }
5619
5620 /* Parse and fetch max feature set */
5621 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5622 hddLog(LOGE, FL("Attr max feature set size failed"));
5623 return -EINVAL;
5624 }
5625 max_feature_sets = nla_get_u32(
5626 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5627 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5628
5629 /* Fill feature combination matrix */
5630 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305631 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5632 WIFI_FEATURE_P2P;
5633
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305634 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5635 WIFI_FEATURE_SOFT_AP;
5636
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305637 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5638 WIFI_FEATURE_SOFT_AP;
5639
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305640 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5641 WIFI_FEATURE_SOFT_AP |
5642 WIFI_FEATURE_P2P;
5643
5644 /* Add more feature combinations here */
5645
5646 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5647 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5648 hddLog(LOG1, "Feature set matrix");
5649 for (i = 0; i < feature_sets; i++)
5650 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5651
5652 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5653 sizeof(u32) * feature_sets +
5654 NLMSG_HDRLEN);
5655
5656 if (reply_skb) {
5657 if (nla_put_u32(reply_skb,
5658 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5659 feature_sets) ||
5660 nla_put(reply_skb,
5661 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5662 sizeof(u32) * feature_sets, feature_set_matrix)) {
5663 hddLog(LOGE, FL("nla put fail"));
5664 kfree_skb(reply_skb);
5665 return -EINVAL;
5666 }
5667
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305668 ret = cfg80211_vendor_cmd_reply(reply_skb);
5669 EXIT();
5670 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305671 }
5672 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5673 return -ENOMEM;
5674
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305675}
5676
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305677static int
5678wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5679 struct wireless_dev *wdev,
5680 const void *data, int data_len)
5681{
5682 int ret = 0;
5683
5684 vos_ssr_protect(__func__);
5685 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5686 data_len);
5687 vos_ssr_unprotect(__func__);
5688
5689 return ret;
5690}
5691
Agarwal Ashish738843c2014-09-25 12:27:56 +05305692static const struct nla_policy
5693wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5694 +1] =
5695{
5696 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5697};
5698
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305699static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305700 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305701 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305702 int data_len)
5703{
5704 struct net_device *dev = wdev->netdev;
5705 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5706 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5707 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5708 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5709 eHalStatus status;
5710 u32 dfsFlag = 0;
5711
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305712 ENTER();
5713
Agarwal Ashish738843c2014-09-25 12:27:56 +05305714 status = wlan_hdd_validate_context(pHddCtx);
5715 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305716 return -EINVAL;
5717 }
5718 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5719 data, data_len,
5720 wlan_hdd_set_no_dfs_flag_config_policy)) {
5721 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5722 return -EINVAL;
5723 }
5724
5725 /* Parse and fetch required bandwidth kbps */
5726 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5727 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5728 return -EINVAL;
5729 }
5730
5731 dfsFlag = nla_get_u32(
5732 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5733 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5734 dfsFlag);
5735
5736 pHddCtx->disable_dfs_flag = dfsFlag;
5737
5738 sme_disable_dfs_channel(hHal, dfsFlag);
5739 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305740
5741 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305742 return 0;
5743}
Atul Mittal115287b2014-07-08 13:26:33 +05305744
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305745static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
5746 struct wireless_dev *wdev,
5747 const void *data,
5748 int data_len)
5749{
5750 int ret = 0;
5751
5752 vos_ssr_protect(__func__);
5753 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
5754 vos_ssr_unprotect(__func__);
5755
5756 return ret;
5757
5758}
5759
Mukul Sharma2a271632014-10-13 14:59:01 +05305760const struct
5761nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
5762{
5763 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
5764 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
5765};
5766
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305767static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05305768 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05305769{
5770
5771 u8 bssid[6] = {0};
5772 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5773 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5774 eHalStatus status = eHAL_STATUS_SUCCESS;
5775 v_U32_t isFwrRoamEnabled = FALSE;
5776 int ret;
5777
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305778 ENTER();
5779
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305780 ret = wlan_hdd_validate_context(pHddCtx);
5781 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305782 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05305783 }
5784
5785 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
5786 data, data_len,
5787 qca_wlan_vendor_attr);
5788 if (ret){
5789 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5790 return -EINVAL;
5791 }
5792
5793 /* Parse and fetch Enable flag */
5794 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
5795 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
5796 return -EINVAL;
5797 }
5798
5799 isFwrRoamEnabled = nla_get_u32(
5800 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5801
5802 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5803
5804 /* Parse and fetch bssid */
5805 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5806 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5807 return -EINVAL;
5808 }
5809
5810 memcpy(bssid, nla_data(
5811 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
5812 sizeof(bssid));
5813 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
5814
5815 //Update roaming
5816 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305817 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05305818 return status;
5819}
5820
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305821static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
5822 struct wireless_dev *wdev, const void *data, int data_len)
5823{
5824 int ret = 0;
5825
5826 vos_ssr_protect(__func__);
5827 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
5828 vos_ssr_unprotect(__func__);
5829
5830 return ret;
5831}
5832
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305833/**
5834 * __wlan_hdd_cfg80211_setband() - set band
5835 * @wiphy: Pointer to wireless phy
5836 * @wdev: Pointer to wireless device
5837 * @data: Pointer to data
5838 * @data_len: Data length
5839 *
5840 * Return: 0 on success, negative errno on failure
5841 */
5842static int
5843__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
5844 struct wireless_dev *wdev,
5845 const void *data,
5846 int data_len)
5847{
5848 struct net_device *dev = wdev->netdev;
5849 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5850 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5851 int ret;
5852 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
5853 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
5854
5855 ENTER();
5856
5857 ret = wlan_hdd_validate_context(hdd_ctx);
5858 if (0 != ret) {
5859 hddLog(LOGE, FL("HDD context is not valid"));
5860 return ret;
5861 }
5862
5863 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
5864 policy)) {
5865 hddLog(LOGE, FL("Invalid ATTR"));
5866 return -EINVAL;
5867 }
5868
5869 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
5870 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
5871 return -EINVAL;
5872 }
5873
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05305874 hdd_ctx->isSetBandByNL = TRUE;
5875 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305876 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05305877 hdd_ctx->isSetBandByNL = FALSE;
5878
5879 EXIT();
5880 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305881}
5882
5883/**
5884 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
5885 * @wiphy: wiphy structure pointer
5886 * @wdev: Wireless device structure pointer
5887 * @data: Pointer to the data received
5888 * @data_len: Length of @data
5889 *
5890 * Return: 0 on success; errno on failure
5891 */
5892static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
5893 struct wireless_dev *wdev,
5894 const void *data,
5895 int data_len)
5896{
5897 int ret = 0;
5898
5899 vos_ssr_protect(__func__);
5900 ret = __wlan_hdd_cfg80211_setband(wiphy,
5901 wdev, data, data_len);
5902 vos_ssr_unprotect(__func__);
5903
5904 return ret;
5905}
5906
Sunil Duttc69bccb2014-05-26 21:30:20 +05305907const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
5908{
Mukul Sharma2a271632014-10-13 14:59:01 +05305909 {
5910 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5911 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
5912 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5913 WIPHY_VENDOR_CMD_NEED_NETDEV |
5914 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305915 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05305916 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05305917
5918 {
5919 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5920 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
5921 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5922 WIPHY_VENDOR_CMD_NEED_NETDEV |
5923 WIPHY_VENDOR_CMD_NEED_RUNNING,
5924 .doit = wlan_hdd_cfg80211_nan_request
5925 },
5926
Sunil Duttc69bccb2014-05-26 21:30:20 +05305927#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5928 {
5929 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5930 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
5931 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5932 WIPHY_VENDOR_CMD_NEED_NETDEV |
5933 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305934 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05305935 },
5936
5937 {
5938 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5939 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
5940 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5941 WIPHY_VENDOR_CMD_NEED_NETDEV |
5942 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305943 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05305944 },
5945
5946 {
5947 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5948 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
5949 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5950 WIPHY_VENDOR_CMD_NEED_NETDEV |
5951 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305952 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05305953 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305954#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305955#ifdef WLAN_FEATURE_EXTSCAN
5956 {
5957 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5958 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
5959 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5960 WIPHY_VENDOR_CMD_NEED_NETDEV |
5961 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305962 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05305963 },
5964 {
5965 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5966 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
5967 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5968 WIPHY_VENDOR_CMD_NEED_NETDEV |
5969 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305970 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05305971 },
5972 {
5973 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5974 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
5975 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5976 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305977 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05305978 },
5979 {
5980 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5981 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
5982 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5983 WIPHY_VENDOR_CMD_NEED_NETDEV |
5984 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305985 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05305986 },
5987 {
5988 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5989 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
5990 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5991 WIPHY_VENDOR_CMD_NEED_NETDEV |
5992 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305993 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05305994 },
5995 {
5996 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5997 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
5998 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5999 WIPHY_VENDOR_CMD_NEED_NETDEV |
6000 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306001 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05306002 },
6003 {
6004 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6005 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
6006 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6007 WIPHY_VENDOR_CMD_NEED_NETDEV |
6008 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306009 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05306010 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05306011 {
6012 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6013 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST,
6014 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6015 WIPHY_VENDOR_CMD_NEED_NETDEV |
6016 WIPHY_VENDOR_CMD_NEED_RUNNING,
6017 .doit = wlan_hdd_cfg80211_extscan_set_ssid_hotlist
6018 },
6019 {
6020 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6021 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST,
6022 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6023 WIPHY_VENDOR_CMD_NEED_NETDEV |
6024 WIPHY_VENDOR_CMD_NEED_RUNNING,
6025 .doit = wlan_hdd_cfg80211_extscan_reset_ssid_hotlist
6026 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05306027#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05306028/*EXT TDLS*/
6029 {
6030 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6031 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
6032 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6033 WIPHY_VENDOR_CMD_NEED_NETDEV |
6034 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306035 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05306036 },
6037 {
6038 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6039 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
6040 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6041 WIPHY_VENDOR_CMD_NEED_NETDEV |
6042 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306043 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05306044 },
6045 {
6046 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6047 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
6048 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6049 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306050 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05306051 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05306052 {
6053 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6054 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
6055 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6056 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306057 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05306058 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05306059 {
6060 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6061 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
6062 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6063 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306064 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05306065 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05306066 {
6067 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6068 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
6069 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6070 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306071 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05306072 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306073 {
6074 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6075 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
6076 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6077 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05306078 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05306079 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05306080 {
6081 .info.vendor_id = QCA_NL80211_VENDOR_ID,
6082 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
6083 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
6084 WIPHY_VENDOR_CMD_NEED_NETDEV |
6085 WIPHY_VENDOR_CMD_NEED_RUNNING,
6086 .doit = wlan_hdd_cfg80211_setband
6087 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05306088};
6089
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006090/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05306091static const
6092struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006093{
6094#ifdef FEATURE_WLAN_CH_AVOID
6095 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05306096 .vendor_id = QCA_NL80211_VENDOR_ID,
6097 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006098 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05306099#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
6100#ifdef WLAN_FEATURE_LINK_LAYER_STATS
6101 {
6102 /* Index = 1*/
6103 .vendor_id = QCA_NL80211_VENDOR_ID,
6104 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
6105 },
6106 {
6107 /* Index = 2*/
6108 .vendor_id = QCA_NL80211_VENDOR_ID,
6109 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
6110 },
6111 {
6112 /* Index = 3*/
6113 .vendor_id = QCA_NL80211_VENDOR_ID,
6114 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
6115 },
6116 {
6117 /* Index = 4*/
6118 .vendor_id = QCA_NL80211_VENDOR_ID,
6119 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
6120 },
6121 {
6122 /* Index = 5*/
6123 .vendor_id = QCA_NL80211_VENDOR_ID,
6124 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
6125 },
6126 {
6127 /* Index = 6*/
6128 .vendor_id = QCA_NL80211_VENDOR_ID,
6129 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
6130 },
6131#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05306132#ifdef WLAN_FEATURE_EXTSCAN
6133 {
6134 .vendor_id = QCA_NL80211_VENDOR_ID,
6135 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
6136 },
6137 {
6138 .vendor_id = QCA_NL80211_VENDOR_ID,
6139 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
6140 },
6141 {
6142 .vendor_id = QCA_NL80211_VENDOR_ID,
6143 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
6144 },
6145 {
6146 .vendor_id = QCA_NL80211_VENDOR_ID,
6147 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
6148 },
6149 {
6150 .vendor_id = QCA_NL80211_VENDOR_ID,
6151 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
6152 },
6153 {
6154 .vendor_id = QCA_NL80211_VENDOR_ID,
6155 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
6156 },
6157 {
6158 .vendor_id = QCA_NL80211_VENDOR_ID,
6159 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
6160 },
6161 {
6162 .vendor_id = QCA_NL80211_VENDOR_ID,
6163 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
6164 },
6165 {
6166 .vendor_id = QCA_NL80211_VENDOR_ID,
6167 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
6168 },
6169 {
6170 .vendor_id = QCA_NL80211_VENDOR_ID,
6171 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
6172 },
Padma, Santhosh Kumar9acee012015-08-21 19:58:01 +05306173 {
6174 .vendor_id = QCA_NL80211_VENDOR_ID,
6175 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SSID_HOTLIST
6176 },
6177 {
6178 .vendor_id = QCA_NL80211_VENDOR_ID,
6179 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SSID_HOTLIST
6180 },
6181 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND_INDEX] = {
6182 .vendor_id = QCA_NL80211_VENDOR_ID,
6183 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_FOUND
6184 },
6185 [QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST_INDEX] = {
6186 .vendor_id = QCA_NL80211_VENDOR_ID,
6187 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_SSID_LOST
6188 },
Dino Mycle6fb96c12014-06-10 11:52:40 +05306189#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05306190/*EXT TDLS*/
6191 {
6192 .vendor_id = QCA_NL80211_VENDOR_ID,
6193 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
6194 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05306195
6196 {
6197 .vendor_id = QCA_NL80211_VENDOR_ID,
6198 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
6199 },
6200
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006201};
6202
Jeff Johnson295189b2012-06-20 16:38:30 -07006203/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306204 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306205 * This function is called by hdd_wlan_startup()
6206 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306207 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07006208 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306209struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07006210{
6211 struct wiphy *wiphy;
6212 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306213 /*
6214 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07006215 */
6216 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
6217
6218 if (!wiphy)
6219 {
6220 /* Print error and jump into err label and free the memory */
6221 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
6222 return NULL;
6223 }
6224
Sunil Duttc69bccb2014-05-26 21:30:20 +05306225
Jeff Johnson295189b2012-06-20 16:38:30 -07006226 return wiphy;
6227}
6228
6229/*
6230 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306231 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07006232 * private ioctl to change the band value
6233 */
6234int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
6235{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306236 int i, j;
6237 eNVChannelEnabledType channelEnabledState;
6238
Jeff Johnsone7245742012-09-05 17:12:55 -07006239 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306240
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306241 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006242 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306243
6244 if (NULL == wiphy->bands[i])
6245 {
6246 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
6247 __func__, i);
6248 continue;
6249 }
6250
6251 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
6252 {
6253 struct ieee80211_supported_band *band = wiphy->bands[i];
6254
6255 channelEnabledState = vos_nv_getChannelEnabledState(
6256 band->channels[j].hw_value);
6257
6258 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
6259 {
Abhishek Singh678227a2014-11-04 10:52:38 +05306260 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306261 continue;
6262 }
6263 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
6264 {
6265 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6266 continue;
6267 }
6268
6269 if (NV_CHANNEL_DISABLE == channelEnabledState ||
6270 NV_CHANNEL_INVALID == channelEnabledState)
6271 {
6272 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6273 }
6274 else if (NV_CHANNEL_DFS == channelEnabledState)
6275 {
6276 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
6277 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
6278 }
6279 else
6280 {
6281 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
6282 |IEEE80211_CHAN_RADAR);
6283 }
6284 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006285 }
6286 return 0;
6287}
6288/*
6289 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306290 * This function is called by hdd_wlan_startup()
6291 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07006292 * This function is used to initialize and register wiphy structure.
6293 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306294int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07006295 struct wiphy *wiphy,
6296 hdd_config_t *pCfg
6297 )
6298{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306299 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05306300 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6301
Jeff Johnsone7245742012-09-05 17:12:55 -07006302 ENTER();
6303
Jeff Johnson295189b2012-06-20 16:38:30 -07006304 /* Now bind the underlying wlan device with wiphy */
6305 set_wiphy_dev(wiphy, dev);
6306
6307 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07006308
Kiet Lam6c583332013-10-14 05:37:09 +05306309#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07006310 /* the flag for the other case would be initialzed in
6311 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07006312 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05306313#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07006314
Amar Singhalfddc28c2013-09-05 13:03:40 -07006315 /* This will disable updating of NL channels from passive to
6316 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306317#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
6318 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
6319#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07006320 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306321#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07006322
Amar Singhala49cbc52013-10-08 18:37:44 -07006323
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006324#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07006325 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
6326 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
6327 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07006328 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306329#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
6330 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
6331#else
6332 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
6333#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006334#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07006335
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006336#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006337 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08006338#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006339 || pCfg->isFastRoamIniFeatureEnabled
6340#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006341#ifdef FEATURE_WLAN_ESE
6342 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006343#endif
6344 )
6345 {
6346 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
6347 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08006348#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006349#ifdef FEATURE_WLAN_TDLS
6350 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
6351 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
6352#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05306353#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05306354 if (pCfg->configPNOScanSupport)
6355 {
6356 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
6357 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
6358 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
6359 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
6360 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05306361#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006362
Abhishek Singh10d85972015-04-17 10:27:23 +05306363#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6364 wiphy->features |= NL80211_FEATURE_HT_IBSS;
6365#endif
6366
Amar Singhalfddc28c2013-09-05 13:03:40 -07006367#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07006368 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
6369 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07006370 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07006371 driver need to determine what to do with both
6372 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07006373
6374 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07006375#else
6376 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07006377#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006378
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306379 wiphy->max_scan_ssids = MAX_SCAN_SSID;
6380
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05306381 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07006382
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306383 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
6384
Jeff Johnson295189b2012-06-20 16:38:30 -07006385 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05306386 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
6387 | BIT(NL80211_IFTYPE_ADHOC)
6388 | BIT(NL80211_IFTYPE_P2P_CLIENT)
6389 | BIT(NL80211_IFTYPE_P2P_GO)
6390 | BIT(NL80211_IFTYPE_AP);
6391
6392 if (VOS_MONITOR_MODE == hdd_get_conparam())
6393 {
6394 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
6395 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006396
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306397 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006398 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306399#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6400 if( pCfg->enableMCC )
6401 {
6402 /* Currently, supports up to two channels */
6403 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006404
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306405 if( !pCfg->allowMCCGODiffBI )
6406 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006407
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306408 }
6409 wiphy->iface_combinations = &wlan_hdd_iface_combination;
6410 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006411#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306412 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006413
Jeff Johnson295189b2012-06-20 16:38:30 -07006414 /* Before registering we need to update the ht capabilitied based
6415 * on ini values*/
6416 if( !pCfg->ShortGI20MhzEnable )
6417 {
6418 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6419 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6420 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6421 }
6422
6423 if( !pCfg->ShortGI40MhzEnable )
6424 {
6425 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
6426 }
6427
6428 if( !pCfg->nChannelBondingMode5GHz )
6429 {
6430 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6431 }
6432
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306433 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05306434 if (true == hdd_is_5g_supported(pHddCtx))
6435 {
6436 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
6437 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306438
6439 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
6440 {
6441
6442 if (NULL == wiphy->bands[i])
6443 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05306444 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306445 __func__, i);
6446 continue;
6447 }
6448
6449 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
6450 {
6451 struct ieee80211_supported_band *band = wiphy->bands[i];
6452
6453 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
6454 {
6455 // Enable social channels for P2P
6456 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
6457 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
6458 else
6459 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6460 continue;
6461 }
6462 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
6463 {
6464 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6465 continue;
6466 }
6467 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006468 }
6469 /*Initialise the supported cipher suite details*/
6470 wiphy->cipher_suites = hdd_cipher_suites;
6471 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
6472
6473 /*signal strength in mBm (100*dBm) */
6474 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
6475
6476#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05306477 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07006478#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006479
Sunil Duttc69bccb2014-05-26 21:30:20 +05306480 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
6481 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006482 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
6483 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
6484
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306485 EXIT();
6486 return 0;
6487}
6488
6489/* In this function we are registering wiphy. */
6490int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
6491{
6492 ENTER();
6493 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006494 if (0 > wiphy_register(wiphy))
6495 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306496 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07006497 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
6498 return -EIO;
6499 }
6500
6501 EXIT();
6502 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306503}
Jeff Johnson295189b2012-06-20 16:38:30 -07006504
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306505/* In this function we are updating channel list when,
6506 regulatory domain is FCC and country code is US.
6507 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
6508 As per FCC smart phone is not a indoor device.
6509 GO should not opeate on indoor channels */
6510void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
6511{
6512 int j;
6513 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6514 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
6515 //Default counrtycode from NV at the time of wiphy initialization.
6516 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
6517 &defaultCountryCode[0]))
6518 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006519 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306520 }
6521 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
6522 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306523 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
6524 {
6525 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
6526 return;
6527 }
6528 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
6529 {
6530 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
6531 // Mark UNII -1 band channel as passive
6532 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
6533 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
6534 }
6535 }
6536}
6537
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306538/* This function registers for all frame which supplicant is interested in */
6539void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006540{
Jeff Johnson295189b2012-06-20 16:38:30 -07006541 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6542 /* Register for all P2P action, public action etc frames */
6543 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6544
Jeff Johnsone7245742012-09-05 17:12:55 -07006545 ENTER();
6546
Jeff Johnson295189b2012-06-20 16:38:30 -07006547 /* Right now we are registering these frame when driver is getting
6548 initialized. Once we will move to 2.6.37 kernel, in which we have
6549 frame register ops, we will move this code as a part of that */
6550 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306551 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006552 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6553
6554 /* GAS Initial Response */
6555 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6556 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306557
Jeff Johnson295189b2012-06-20 16:38:30 -07006558 /* GAS Comeback Request */
6559 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6560 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6561
6562 /* GAS Comeback Response */
6563 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6564 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6565
6566 /* P2P Public Action */
6567 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306568 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006569 P2P_PUBLIC_ACTION_FRAME_SIZE );
6570
6571 /* P2P Action */
6572 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6573 (v_U8_t*)P2P_ACTION_FRAME,
6574 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07006575
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05306576 /* WNM BSS Transition Request frame */
6577 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6578 (v_U8_t*)WNM_BSS_ACTION_FRAME,
6579 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006580
6581 /* WNM-Notification */
6582 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6583 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6584 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006585}
6586
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306587void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006588{
Jeff Johnson295189b2012-06-20 16:38:30 -07006589 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6590 /* Register for all P2P action, public action etc frames */
6591 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6592
Jeff Johnsone7245742012-09-05 17:12:55 -07006593 ENTER();
6594
Jeff Johnson295189b2012-06-20 16:38:30 -07006595 /* Right now we are registering these frame when driver is getting
6596 initialized. Once we will move to 2.6.37 kernel, in which we have
6597 frame register ops, we will move this code as a part of that */
6598 /* GAS Initial Request */
6599
6600 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6601 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6602
6603 /* GAS Initial Response */
6604 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6605 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306606
Jeff Johnson295189b2012-06-20 16:38:30 -07006607 /* GAS Comeback Request */
6608 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6609 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6610
6611 /* GAS Comeback Response */
6612 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6613 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6614
6615 /* P2P Public Action */
6616 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306617 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006618 P2P_PUBLIC_ACTION_FRAME_SIZE );
6619
6620 /* P2P Action */
6621 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6622 (v_U8_t*)P2P_ACTION_FRAME,
6623 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006624 /* WNM-Notification */
6625 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6626 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6627 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006628}
6629
6630#ifdef FEATURE_WLAN_WAPI
6631void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05306632 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006633{
6634 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6635 tCsrRoamSetKey setKey;
6636 v_BOOL_t isConnected = TRUE;
6637 int status = 0;
6638 v_U32_t roamId= 0xFF;
6639 tANI_U8 *pKeyPtr = NULL;
6640 int n = 0;
6641
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306642 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
6643 __func__, hdd_device_modetoString(pAdapter->device_mode),
6644 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006645
Gopichand Nakkalae7480202013-02-11 15:24:22 +05306646 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006647 setKey.keyId = key_index; // Store Key ID
6648 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
6649 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
6650 setKey.paeRole = 0 ; // the PAE role
6651 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
6652 {
6653 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
6654 }
6655 else
6656 {
6657 isConnected = hdd_connIsConnected(pHddStaCtx);
6658 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
6659 }
6660 setKey.keyLength = key_Len;
6661 pKeyPtr = setKey.Key;
6662 memcpy( pKeyPtr, key, key_Len);
6663
Arif Hussain6d2a3322013-11-17 19:50:10 -08006664 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07006665 __func__, key_Len);
6666 for (n = 0 ; n < key_Len; n++)
6667 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
6668 __func__,n,setKey.Key[n]);
6669
6670 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
6671 if ( isConnected )
6672 {
6673 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
6674 pAdapter->sessionId, &setKey, &roamId );
6675 }
6676 if ( status != 0 )
6677 {
6678 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6679 "[%4d] sme_RoamSetKey returned ERROR status= %d",
6680 __LINE__, status );
6681 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
6682 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05306683 /* Need to clear any trace of key value in the memory.
6684 * Thus zero out the memory even though it is local
6685 * variable.
6686 */
6687 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006688}
6689#endif /* FEATURE_WLAN_WAPI*/
6690
6691#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306692int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006693 beacon_data_t **ppBeacon,
6694 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006695#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306696int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006697 beacon_data_t **ppBeacon,
6698 struct cfg80211_beacon_data *params,
6699 int dtim_period)
6700#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306701{
Jeff Johnson295189b2012-06-20 16:38:30 -07006702 int size;
6703 beacon_data_t *beacon = NULL;
6704 beacon_data_t *old = NULL;
6705 int head_len,tail_len;
6706
Jeff Johnsone7245742012-09-05 17:12:55 -07006707 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006708 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306709 {
6710 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6711 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006712 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306713 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006714
6715 old = pAdapter->sessionCtx.ap.beacon;
6716
6717 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306718 {
6719 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6720 FL("session(%d) old and new heads points to NULL"),
6721 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006722 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306723 }
6724
6725 if (params->tail && !params->tail_len)
6726 {
6727 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6728 FL("tail_len is zero but tail is not NULL"));
6729 return -EINVAL;
6730 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006731
Jeff Johnson295189b2012-06-20 16:38:30 -07006732#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
6733 /* Kernel 3.0 is not updating dtim_period for set beacon */
6734 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306735 {
6736 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6737 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006738 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306739 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006740#endif
6741
6742 if(params->head)
6743 head_len = params->head_len;
6744 else
6745 head_len = old->head_len;
6746
6747 if(params->tail || !old)
6748 tail_len = params->tail_len;
6749 else
6750 tail_len = old->tail_len;
6751
6752 size = sizeof(beacon_data_t) + head_len + tail_len;
6753
6754 beacon = kzalloc(size, GFP_KERNEL);
6755
6756 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306757 {
6758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6759 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006760 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306761 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006762
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006763#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006764 if(params->dtim_period || !old )
6765 beacon->dtim_period = params->dtim_period;
6766 else
6767 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006768#else
6769 if(dtim_period || !old )
6770 beacon->dtim_period = dtim_period;
6771 else
6772 beacon->dtim_period = old->dtim_period;
6773#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306774
Jeff Johnson295189b2012-06-20 16:38:30 -07006775 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6776 beacon->tail = beacon->head + head_len;
6777 beacon->head_len = head_len;
6778 beacon->tail_len = tail_len;
6779
6780 if(params->head) {
6781 memcpy (beacon->head,params->head,beacon->head_len);
6782 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306783 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07006784 if(old)
6785 memcpy (beacon->head,old->head,beacon->head_len);
6786 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306787
Jeff Johnson295189b2012-06-20 16:38:30 -07006788 if(params->tail) {
6789 memcpy (beacon->tail,params->tail,beacon->tail_len);
6790 }
6791 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306792 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07006793 memcpy (beacon->tail,old->tail,beacon->tail_len);
6794 }
6795
6796 *ppBeacon = beacon;
6797
6798 kfree(old);
6799
6800 return 0;
6801
6802}
Jeff Johnson295189b2012-06-20 16:38:30 -07006803
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05306804v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
6805#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6806 const v_U8_t *pIes,
6807#else
6808 v_U8_t *pIes,
6809#endif
6810 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006811{
6812 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05306813 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07006814 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306815
Jeff Johnson295189b2012-06-20 16:38:30 -07006816 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306817 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006818 elem_id = ptr[0];
6819 elem_len = ptr[1];
6820 left -= 2;
6821 if(elem_len > left)
6822 {
6823 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006824 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006825 eid,elem_len,left);
6826 return NULL;
6827 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306828 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006829 {
6830 return ptr;
6831 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306832
Jeff Johnson295189b2012-06-20 16:38:30 -07006833 left -= elem_len;
6834 ptr += (elem_len + 2);
6835 }
6836 return NULL;
6837}
6838
Jeff Johnson295189b2012-06-20 16:38:30 -07006839/* Check if rate is 11g rate or not */
6840static int wlan_hdd_rate_is_11g(u8 rate)
6841{
Sanjay Devnani28322e22013-06-21 16:13:40 -07006842 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006843 u8 i;
6844 for (i = 0; i < 8; i++)
6845 {
6846 if(rate == gRateArray[i])
6847 return TRUE;
6848 }
6849 return FALSE;
6850}
6851
6852/* Check for 11g rate and set proper 11g only mode */
6853static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
6854 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
6855{
6856 u8 i, num_rates = pIe[0];
6857
6858 pIe += 1;
6859 for ( i = 0; i < num_rates; i++)
6860 {
6861 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
6862 {
6863 /* If rate set have 11g rate than change the mode to 11G */
6864 *pSapHw_mode = eSAP_DOT11_MODE_11g;
6865 if (pIe[i] & BASIC_RATE_MASK)
6866 {
6867 /* If we have 11g rate as basic rate, it means mode
6868 is 11g only mode.
6869 */
6870 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
6871 *pCheckRatesfor11g = FALSE;
6872 }
6873 }
6874 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
6875 {
6876 *require_ht = TRUE;
6877 }
6878 }
6879 return;
6880}
6881
6882static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
6883{
6884 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6885 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6886 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6887 u8 checkRatesfor11g = TRUE;
6888 u8 require_ht = FALSE;
6889 u8 *pIe=NULL;
6890
6891 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
6892
6893 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
6894 pBeacon->head_len, WLAN_EID_SUPP_RATES);
6895 if (pIe != NULL)
6896 {
6897 pIe += 1;
6898 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6899 &pConfig->SapHw_mode);
6900 }
6901
6902 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6903 WLAN_EID_EXT_SUPP_RATES);
6904 if (pIe != NULL)
6905 {
6906
6907 pIe += 1;
6908 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6909 &pConfig->SapHw_mode);
6910 }
6911
6912 if( pConfig->channel > 14 )
6913 {
6914 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
6915 }
6916
6917 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6918 WLAN_EID_HT_CAPABILITY);
6919
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306920 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006921 {
6922 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
6923 if(require_ht)
6924 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
6925 }
6926}
6927
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306928static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
6929 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
6930{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006931 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306932 v_U8_t *pIe = NULL;
6933 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6934
6935 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
6936 pBeacon->tail, pBeacon->tail_len);
6937
6938 if (pIe)
6939 {
6940 ielen = pIe[1] + 2;
6941 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6942 {
6943 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
6944 }
6945 else
6946 {
6947 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
6948 return -EINVAL;
6949 }
6950 *total_ielen += ielen;
6951 }
6952 return 0;
6953}
6954
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006955static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
6956 v_U8_t *genie, v_U8_t *total_ielen)
6957{
6958 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6959 int left = pBeacon->tail_len;
6960 v_U8_t *ptr = pBeacon->tail;
6961 v_U8_t elem_id, elem_len;
6962 v_U16_t ielen = 0;
6963
6964 if ( NULL == ptr || 0 == left )
6965 return;
6966
6967 while (left >= 2)
6968 {
6969 elem_id = ptr[0];
6970 elem_len = ptr[1];
6971 left -= 2;
6972 if (elem_len > left)
6973 {
6974 hddLog( VOS_TRACE_LEVEL_ERROR,
6975 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
6976 elem_id, elem_len, left);
6977 return;
6978 }
6979 if (IE_EID_VENDOR == elem_id)
6980 {
6981 /* skipping the VSIE's which we don't want to include or
6982 * it will be included by existing code
6983 */
6984 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
6985#ifdef WLAN_FEATURE_WFD
6986 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
6987#endif
6988 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6989 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6990 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
6991 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6992 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
6993 {
6994 ielen = ptr[1] + 2;
6995 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6996 {
6997 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
6998 *total_ielen += ielen;
6999 }
7000 else
7001 {
7002 hddLog( VOS_TRACE_LEVEL_ERROR,
7003 "IE Length is too big "
7004 "IEs eid=%d elem_len=%d total_ie_lent=%d",
7005 elem_id, elem_len, *total_ielen);
7006 }
7007 }
7008 }
7009
7010 left -= elem_len;
7011 ptr += (elem_len + 2);
7012 }
7013 return;
7014}
7015
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007016#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007017static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
7018 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007019#else
7020static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
7021 struct cfg80211_beacon_data *params)
7022#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007023{
7024 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307025 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007026 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07007027 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07007028
7029 genie = vos_mem_malloc(MAX_GENIE_LEN);
7030
7031 if(genie == NULL) {
7032
7033 return -ENOMEM;
7034 }
7035
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307036 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7037 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007038 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307039 hddLog(LOGE,
7040 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307041 ret = -EINVAL;
7042 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007043 }
7044
7045#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307046 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7047 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
7048 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307049 hddLog(LOGE,
7050 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307051 ret = -EINVAL;
7052 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007053 }
7054#endif
7055
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307056 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
7057 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07007058 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307059 hddLog(LOGE,
7060 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307061 ret = -EINVAL;
7062 goto done;
7063 }
7064
7065 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
7066 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07007067 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07007068 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007069
7070 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7071 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
7072 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
7073 {
7074 hddLog(LOGE,
7075 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007076 ret = -EINVAL;
7077 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007078 }
7079
7080 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7081 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
7082 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7083 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7084 ==eHAL_STATUS_FAILURE)
7085 {
7086 hddLog(LOGE,
7087 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007088 ret = -EINVAL;
7089 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007090 }
7091
7092 // Added for ProResp IE
7093 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
7094 {
7095 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
7096 u8 probe_rsp_ie_len[3] = {0};
7097 u8 counter = 0;
7098 /* Check Probe Resp Length if it is greater then 255 then Store
7099 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
7100 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
7101 Store More then 255 bytes into One Variable.
7102 */
7103 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
7104 {
7105 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
7106 {
7107 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
7108 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
7109 }
7110 else
7111 {
7112 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
7113 rem_probe_resp_ie_len = 0;
7114 }
7115 }
7116
7117 rem_probe_resp_ie_len = 0;
7118
7119 if (probe_rsp_ie_len[0] > 0)
7120 {
7121 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7122 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
7123 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7124 probe_rsp_ie_len[0], NULL,
7125 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7126 {
7127 hddLog(LOGE,
7128 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007129 ret = -EINVAL;
7130 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007131 }
7132 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
7133 }
7134
7135 if (probe_rsp_ie_len[1] > 0)
7136 {
7137 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7138 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
7139 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7140 probe_rsp_ie_len[1], NULL,
7141 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7142 {
7143 hddLog(LOGE,
7144 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007145 ret = -EINVAL;
7146 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007147 }
7148 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
7149 }
7150
7151 if (probe_rsp_ie_len[2] > 0)
7152 {
7153 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7154 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
7155 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
7156 probe_rsp_ie_len[2], NULL,
7157 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7158 {
7159 hddLog(LOGE,
7160 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007161 ret = -EINVAL;
7162 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007163 }
7164 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
7165 }
7166
7167 if (probe_rsp_ie_len[1] == 0 )
7168 {
7169 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7170 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
7171 eANI_BOOLEAN_FALSE) )
7172 {
7173 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007174 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007175 }
7176 }
7177
7178 if (probe_rsp_ie_len[2] == 0 )
7179 {
7180 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7181 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
7182 eANI_BOOLEAN_FALSE) )
7183 {
7184 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007185 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007186 }
7187 }
7188
7189 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7190 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
7191 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7192 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7193 == eHAL_STATUS_FAILURE)
7194 {
7195 hddLog(LOGE,
7196 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007197 ret = -EINVAL;
7198 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007199 }
7200 }
7201 else
7202 {
7203 // Reset WNI_CFG_PROBE_RSP Flags
7204 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
7205
7206 hddLog(VOS_TRACE_LEVEL_INFO,
7207 "%s: No Probe Response IE received in set beacon",
7208 __func__);
7209 }
7210
7211 // Added for AssocResp IE
7212 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
7213 {
7214 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7215 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
7216 params->assocresp_ies_len, NULL,
7217 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
7218 {
7219 hddLog(LOGE,
7220 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007221 ret = -EINVAL;
7222 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007223 }
7224
7225 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7226 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
7227 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
7228 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
7229 == eHAL_STATUS_FAILURE)
7230 {
7231 hddLog(LOGE,
7232 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07007233 ret = -EINVAL;
7234 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07007235 }
7236 }
7237 else
7238 {
7239 hddLog(VOS_TRACE_LEVEL_INFO,
7240 "%s: No Assoc Response IE received in set beacon",
7241 __func__);
7242
7243 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
7244 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7245 eANI_BOOLEAN_FALSE) )
7246 {
7247 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007248 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007249 }
7250 }
7251
Jeff Johnsone7245742012-09-05 17:12:55 -07007252done:
Jeff Johnson295189b2012-06-20 16:38:30 -07007253 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05307254 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007255}
Jeff Johnson295189b2012-06-20 16:38:30 -07007256
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307257/*
Jeff Johnson295189b2012-06-20 16:38:30 -07007258 * FUNCTION: wlan_hdd_validate_operation_channel
7259 * called by wlan_hdd_cfg80211_start_bss() and
7260 * wlan_hdd_cfg80211_set_channel()
7261 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307262 * channel list.
7263 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07007264VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07007265{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307266
Jeff Johnson295189b2012-06-20 16:38:30 -07007267 v_U32_t num_ch = 0;
7268 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
7269 u32 indx = 0;
7270 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307271 v_U8_t fValidChannel = FALSE, count = 0;
7272 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307273
Jeff Johnson295189b2012-06-20 16:38:30 -07007274 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7275
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307276 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07007277 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307278 /* Validate the channel */
7279 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07007280 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307281 if ( channel == rfChannels[count].channelNum )
7282 {
7283 fValidChannel = TRUE;
7284 break;
7285 }
7286 }
7287 if (fValidChannel != TRUE)
7288 {
7289 hddLog(VOS_TRACE_LEVEL_ERROR,
7290 "%s: Invalid Channel [%d]", __func__, channel);
7291 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07007292 }
7293 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307294 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007295 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05307296 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
7297 valid_ch, &num_ch))
7298 {
7299 hddLog(VOS_TRACE_LEVEL_ERROR,
7300 "%s: failed to get valid channel list", __func__);
7301 return VOS_STATUS_E_FAILURE;
7302 }
7303 for (indx = 0; indx < num_ch; indx++)
7304 {
7305 if (channel == valid_ch[indx])
7306 {
7307 break;
7308 }
7309 }
7310
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05307311 if (indx >= num_ch)
7312 {
7313 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
7314 {
7315 eCsrBand band;
7316 unsigned int freq;
7317
7318 sme_GetFreqBand(hHal, &band);
7319
7320 if (eCSR_BAND_5G == band)
7321 {
7322#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
7323 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
7324 {
7325 freq = ieee80211_channel_to_frequency(channel,
7326 IEEE80211_BAND_2GHZ);
7327 }
7328 else
7329 {
7330 freq = ieee80211_channel_to_frequency(channel,
7331 IEEE80211_BAND_5GHZ);
7332 }
7333#else
7334 freq = ieee80211_channel_to_frequency(channel);
7335#endif
7336 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
7337 return VOS_STATUS_SUCCESS;
7338 }
7339 }
7340
7341 hddLog(VOS_TRACE_LEVEL_ERROR,
7342 "%s: Invalid Channel [%d]", __func__, channel);
7343 return VOS_STATUS_E_FAILURE;
7344 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007345 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05307346
Jeff Johnson295189b2012-06-20 16:38:30 -07007347 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307348
Jeff Johnson295189b2012-06-20 16:38:30 -07007349}
7350
Viral Modi3a32cc52013-02-08 11:14:52 -08007351/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307352 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08007353 * This function is used to set the channel number
7354 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307355static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08007356 struct ieee80211_channel *chan,
7357 enum nl80211_channel_type channel_type
7358 )
7359{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307360 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08007361 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07007362 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08007363 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307364 hdd_context_t *pHddCtx;
7365 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007366
7367 ENTER();
7368
7369 if( NULL == dev )
7370 {
7371 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007372 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08007373 return -ENODEV;
7374 }
7375 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307376
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307377 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7378 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
7379 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08007380 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307381 "%s: device_mode = %s (%d) freq = %d", __func__,
7382 hdd_device_modetoString(pAdapter->device_mode),
7383 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307384
7385 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7386 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307387 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08007388 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307389 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007390 }
7391
7392 /*
7393 * Do freq to chan conversion
7394 * TODO: for 11a
7395 */
7396
7397 channel = ieee80211_frequency_to_channel(freq);
7398
7399 /* Check freq range */
7400 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
7401 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
7402 {
7403 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007404 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08007405 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
7406 WNI_CFG_CURRENT_CHANNEL_STAMAX);
7407 return -EINVAL;
7408 }
7409
7410 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7411
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05307412 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
7413 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08007414 {
7415 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
7416 {
7417 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007418 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08007419 return -EINVAL;
7420 }
7421 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7422 "%s: set channel to [%d] for device mode =%d",
7423 __func__, channel,pAdapter->device_mode);
7424 }
7425 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08007426 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08007427 )
7428 {
7429 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7430 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
7431 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7432
7433 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
7434 {
7435 /* Link is up then return cant set channel*/
7436 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007437 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08007438 return -EINVAL;
7439 }
7440
7441 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
7442 pHddStaCtx->conn_info.operationChannel = channel;
7443 pRoamProfile->ChannelInfo.ChannelList =
7444 &pHddStaCtx->conn_info.operationChannel;
7445 }
7446 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08007447 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08007448 )
7449 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307450 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
7451 {
7452 if(VOS_STATUS_SUCCESS !=
7453 wlan_hdd_validate_operation_channel(pAdapter,channel))
7454 {
7455 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007456 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307457 return -EINVAL;
7458 }
7459 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7460 }
7461 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08007462 {
7463 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
7464
7465 /* If auto channel selection is configured as enable/ 1 then ignore
7466 channel set by supplicant
7467 */
7468 if ( cfg_param->apAutoChannelSelection )
7469 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307470 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
7471 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08007472 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307473 "%s: set channel to auto channel (0) for device mode =%s (%d)",
7474 __func__, hdd_device_modetoString(pAdapter->device_mode),
7475 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08007476 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307477 else
7478 {
7479 if(VOS_STATUS_SUCCESS !=
7480 wlan_hdd_validate_operation_channel(pAdapter,channel))
7481 {
7482 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007483 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307484 return -EINVAL;
7485 }
7486 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7487 }
Viral Modi3a32cc52013-02-08 11:14:52 -08007488 }
7489 }
7490 else
7491 {
7492 hddLog(VOS_TRACE_LEVEL_FATAL,
7493 "%s: Invalid device mode failed to set valid channel", __func__);
7494 return -EINVAL;
7495 }
7496 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307497 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007498}
7499
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307500static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
7501 struct net_device *dev,
7502 struct ieee80211_channel *chan,
7503 enum nl80211_channel_type channel_type
7504 )
7505{
7506 int ret;
7507
7508 vos_ssr_protect(__func__);
7509 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
7510 vos_ssr_unprotect(__func__);
7511
7512 return ret;
7513}
7514
Jeff Johnson295189b2012-06-20 16:38:30 -07007515#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7516static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7517 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007518#else
7519static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7520 struct cfg80211_beacon_data *params,
7521 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307522 enum nl80211_hidden_ssid hidden_ssid,
7523 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007524#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007525{
7526 tsap_Config_t *pConfig;
7527 beacon_data_t *pBeacon = NULL;
7528 struct ieee80211_mgmt *pMgmt_frame;
7529 v_U8_t *pIe=NULL;
7530 v_U16_t capab_info;
7531 eCsrAuthType RSNAuthType;
7532 eCsrEncryptionType RSNEncryptType;
7533 eCsrEncryptionType mcRSNEncryptType;
7534 int status = VOS_STATUS_SUCCESS;
7535 tpWLAN_SAPEventCB pSapEventCallback;
7536 hdd_hostapd_state_t *pHostapdState;
7537 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
7538 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307539 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007540 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307541 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07007542 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08007543 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05307544 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07007545 v_BOOL_t MFPCapable = VOS_FALSE;
7546 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307547 v_BOOL_t sapEnable11AC =
7548 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07007549 ENTER();
7550
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307551 iniConfig = pHddCtx->cfg_ini;
7552
Jeff Johnson295189b2012-06-20 16:38:30 -07007553 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
7554
7555 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7556
7557 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7558
7559 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
7560
7561 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
7562
7563 //channel is already set in the set_channel Call back
7564 //pConfig->channel = pCommitConfig->channel;
7565
7566 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307567 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07007568 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
7569
7570 pConfig->dtim_period = pBeacon->dtim_period;
7571
Arif Hussain6d2a3322013-11-17 19:50:10 -08007572 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07007573 pConfig->dtim_period);
7574
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08007575 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07007576 {
7577 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007578 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05307579 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
7580 {
7581 tANI_BOOLEAN restartNeeded;
7582 pConfig->ieee80211d = 1;
7583 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
7584 sme_setRegInfo(hHal, pConfig->countryCode);
7585 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
7586 }
7587 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07007588 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07007589 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07007590 pConfig->ieee80211d = 1;
7591 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
7592 sme_setRegInfo(hHal, pConfig->countryCode);
7593 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07007594 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007595 else
7596 {
7597 pConfig->ieee80211d = 0;
7598 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307599 /*
7600 * If auto channel is configured i.e. channel is 0,
7601 * so skip channel validation.
7602 */
7603 if( AUTO_CHANNEL_SELECT != pConfig->channel )
7604 {
7605 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
7606 {
7607 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007608 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307609 return -EINVAL;
7610 }
7611 }
7612 else
7613 {
7614 if(1 != pHddCtx->is_dynamic_channel_range_set)
7615 {
7616 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
7617 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
7618 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
7619 }
7620 pHddCtx->is_dynamic_channel_range_set = 0;
7621 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007622 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007623 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007624 {
7625 pConfig->ieee80211d = 0;
7626 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307627
7628#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7629 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7630 pConfig->authType = eSAP_OPEN_SYSTEM;
7631 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7632 pConfig->authType = eSAP_SHARED_KEY;
7633 else
7634 pConfig->authType = eSAP_AUTO_SWITCH;
7635#else
7636 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7637 pConfig->authType = eSAP_OPEN_SYSTEM;
7638 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7639 pConfig->authType = eSAP_SHARED_KEY;
7640 else
7641 pConfig->authType = eSAP_AUTO_SWITCH;
7642#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007643
7644 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307645
7646 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07007647 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
7648
7649 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
7650
7651 /*Set wps station to configured*/
7652 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
7653
7654 if(pIe)
7655 {
7656 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
7657 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007658 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07007659 return -EINVAL;
7660 }
7661 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
7662 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007663 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07007664 /* Check 15 bit of WPS IE as it contain information for wps state
7665 * WPS state
7666 */
7667 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
7668 {
7669 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
7670 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
7671 {
7672 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
7673 }
7674 }
7675 }
7676 else
7677 {
7678 pConfig->wps_state = SAP_WPS_DISABLED;
7679 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307680 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07007681
c_hpothufe599e92014-06-16 11:38:55 +05307682 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7683 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7684 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
7685 eCSR_ENCRYPT_TYPE_NONE;
7686
Jeff Johnson295189b2012-06-20 16:38:30 -07007687 pConfig->RSNWPAReqIELength = 0;
7688 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307689 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007690 WLAN_EID_RSN);
7691 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307692 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007693 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7694 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7695 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307696 /* The actual processing may eventually be more extensive than
7697 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07007698 * by the app.
7699 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307700 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007701 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7702 &RSNEncryptType,
7703 &mcRSNEncryptType,
7704 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007705 &MFPCapable,
7706 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007707 pConfig->pRSNWPAReqIE[1]+2,
7708 pConfig->pRSNWPAReqIE );
7709
7710 if( VOS_STATUS_SUCCESS == status )
7711 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307712 /* Now copy over all the security attributes you have
7713 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007714 * */
7715 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7716 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7717 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7718 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307719 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007720 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007721 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7722 }
7723 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307724
Jeff Johnson295189b2012-06-20 16:38:30 -07007725 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7726 pBeacon->tail, pBeacon->tail_len);
7727
7728 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
7729 {
7730 if (pConfig->pRSNWPAReqIE)
7731 {
7732 /*Mixed mode WPA/WPA2*/
7733 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
7734 pConfig->RSNWPAReqIELength += pIe[1] + 2;
7735 }
7736 else
7737 {
7738 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7739 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7740 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307741 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007742 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7743 &RSNEncryptType,
7744 &mcRSNEncryptType,
7745 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007746 &MFPCapable,
7747 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007748 pConfig->pRSNWPAReqIE[1]+2,
7749 pConfig->pRSNWPAReqIE );
7750
7751 if( VOS_STATUS_SUCCESS == status )
7752 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307753 /* Now copy over all the security attributes you have
7754 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007755 * */
7756 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7757 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7758 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7759 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307760 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007761 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007762 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7763 }
7764 }
7765 }
7766
Jeff Johnson4416a782013-03-25 14:17:50 -07007767 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
7768 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
7769 return -EINVAL;
7770 }
7771
Jeff Johnson295189b2012-06-20 16:38:30 -07007772 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
7773
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007774#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007775 if (params->ssid != NULL)
7776 {
7777 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
7778 pConfig->SSIDinfo.ssid.length = params->ssid_len;
7779 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7780 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7781 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007782#else
7783 if (ssid != NULL)
7784 {
7785 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
7786 pConfig->SSIDinfo.ssid.length = ssid_len;
7787 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7788 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7789 }
7790#endif
7791
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307792 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07007793 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307794
Jeff Johnson295189b2012-06-20 16:38:30 -07007795 /* default value */
7796 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7797 pConfig->num_accept_mac = 0;
7798 pConfig->num_deny_mac = 0;
7799
7800 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7801 pBeacon->tail, pBeacon->tail_len);
7802
7803 /* pIe for black list is following form:
7804 type : 1 byte
7805 length : 1 byte
7806 OUI : 4 bytes
7807 acl type : 1 byte
7808 no of mac addr in black list: 1 byte
7809 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307810 */
7811 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007812 {
7813 pConfig->SapMacaddr_acl = pIe[6];
7814 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007815 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007816 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307817 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
7818 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007819 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7820 for (i = 0; i < pConfig->num_deny_mac; i++)
7821 {
7822 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7823 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307824 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007825 }
7826 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7827 pBeacon->tail, pBeacon->tail_len);
7828
7829 /* pIe for white list is following form:
7830 type : 1 byte
7831 length : 1 byte
7832 OUI : 4 bytes
7833 acl type : 1 byte
7834 no of mac addr in white list: 1 byte
7835 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307836 */
7837 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007838 {
7839 pConfig->SapMacaddr_acl = pIe[6];
7840 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007841 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007842 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307843 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
7844 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007845 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7846 for (i = 0; i < pConfig->num_accept_mac; i++)
7847 {
7848 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7849 acl_entry++;
7850 }
7851 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307852
Jeff Johnson295189b2012-06-20 16:38:30 -07007853 wlan_hdd_set_sapHwmode(pHostapdAdapter);
7854
Jeff Johnsone7245742012-09-05 17:12:55 -07007855#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007856 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307857 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
7858 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05307859 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
7860 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007861 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
7862 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307863 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
7864 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07007865 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307866 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07007867 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307868 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007869
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307870 /* If ACS disable and selected channel <= 14
7871 * OR
7872 * ACS enabled and ACS operating band is choosen as 2.4
7873 * AND
7874 * VHT in 2.4G Disabled
7875 * THEN
7876 * Fallback to 11N mode
7877 */
7878 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
7879 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05307880 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307881 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007882 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307883 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
7884 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007885 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
7886 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007887 }
7888#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307889
Jeff Johnson295189b2012-06-20 16:38:30 -07007890 // ht_capab is not what the name conveys,this is used for protection bitmap
7891 pConfig->ht_capab =
7892 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
7893
7894 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
7895 {
7896 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
7897 return -EINVAL;
7898 }
7899
7900 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307901 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07007902 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
7903 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307904 pConfig->obssProtEnabled =
7905 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07007906
Chet Lanctot8cecea22014-02-11 19:09:36 -08007907#ifdef WLAN_FEATURE_11W
7908 pConfig->mfpCapable = MFPCapable;
7909 pConfig->mfpRequired = MFPRequired;
7910 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
7911 pConfig->mfpCapable, pConfig->mfpRequired);
7912#endif
7913
Arif Hussain6d2a3322013-11-17 19:50:10 -08007914 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07007915 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007916 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
7917 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
7918 (int)pConfig->channel);
7919 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
7920 pConfig->SapHw_mode, pConfig->privacy,
7921 pConfig->authType);
7922 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
7923 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
7924 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
7925 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07007926
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307927 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007928 {
7929 //Bss already started. just return.
7930 //TODO Probably it should update some beacon params.
7931 hddLog( LOGE, "Bss Already started...Ignore the request");
7932 EXIT();
7933 return 0;
7934 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307935
Agarwal Ashish51325b52014-06-16 16:50:49 +05307936 if (vos_max_concurrent_connections_reached()) {
7937 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7938 return -EINVAL;
7939 }
7940
Jeff Johnson295189b2012-06-20 16:38:30 -07007941 pConfig->persona = pHostapdAdapter->device_mode;
7942
Peng Xu2446a892014-09-05 17:21:18 +05307943 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
7944 if ( NULL != psmeConfig)
7945 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307946 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05307947 sme_GetConfigParam(hHal, psmeConfig);
7948 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307949#ifdef WLAN_FEATURE_AP_HT40_24G
7950 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
7951 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
7952 && pHddCtx->cfg_ini->apHT40_24GEnabled)
7953 {
7954 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
7955 sme_UpdateConfig (hHal, psmeConfig);
7956 }
7957#endif
Peng Xu2446a892014-09-05 17:21:18 +05307958 vos_mem_free(psmeConfig);
7959 }
Peng Xuafc34e32014-09-25 13:23:55 +05307960 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05307961
Jeff Johnson295189b2012-06-20 16:38:30 -07007962 pSapEventCallback = hdd_hostapd_SAPEventCB;
7963 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
7964 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
7965 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007966 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007967 return -EINVAL;
7968 }
7969
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307970 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07007971 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
7972
7973 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307974
Jeff Johnson295189b2012-06-20 16:38:30 -07007975 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307976 {
7977 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007978 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07007979 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07007980 VOS_ASSERT(0);
7981 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307982
Jeff Johnson295189b2012-06-20 16:38:30 -07007983 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05307984 /* Initialize WMM configuation */
7985 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307986 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007987
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007988#ifdef WLAN_FEATURE_P2P_DEBUG
7989 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
7990 {
7991 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
7992 {
7993 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7994 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007995 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007996 }
7997 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
7998 {
7999 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
8000 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08008001 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008002 }
8003 }
8004#endif
8005
Jeff Johnson295189b2012-06-20 16:38:30 -07008006 pHostapdState->bCommit = TRUE;
8007 EXIT();
8008
8009 return 0;
8010}
8011
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008012#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308013static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308014 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07008015 struct beacon_parameters *params)
8016{
8017 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308018 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308019 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008020
8021 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308022
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308023 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8024 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
8025 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308026 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
8027 hdd_device_modetoString(pAdapter->device_mode),
8028 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008029
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308030 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8031 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308032 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008033 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308034 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008035 }
8036
Agarwal Ashish51325b52014-06-16 16:50:49 +05308037 if (vos_max_concurrent_connections_reached()) {
8038 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8039 return -EINVAL;
8040 }
8041
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308042 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008043 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008044 )
8045 {
8046 beacon_data_t *old,*new;
8047
8048 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308049
Jeff Johnson295189b2012-06-20 16:38:30 -07008050 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308051 {
8052 hddLog(VOS_TRACE_LEVEL_WARN,
8053 FL("already beacon info added to session(%d)"),
8054 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008055 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308056 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008057
8058 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
8059
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308060 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07008061 {
8062 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008063 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008064 return -EINVAL;
8065 }
8066
8067 pAdapter->sessionCtx.ap.beacon = new;
8068
8069 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
8070 }
8071
8072 EXIT();
8073 return status;
8074}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308075
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308076static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
8077 struct net_device *dev,
8078 struct beacon_parameters *params)
8079{
8080 int ret;
8081
8082 vos_ssr_protect(__func__);
8083 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
8084 vos_ssr_unprotect(__func__);
8085
8086 return ret;
8087}
8088
8089static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008090 struct net_device *dev,
8091 struct beacon_parameters *params)
8092{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308093 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308094 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8095 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308096 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008097
8098 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308099
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308100 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8101 TRACE_CODE_HDD_CFG80211_SET_BEACON,
8102 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
8103 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8104 __func__, hdd_device_modetoString(pAdapter->device_mode),
8105 pAdapter->device_mode);
8106
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308107 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8108 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308109 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008110 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308111 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008112 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308113
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308114 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008115 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308116 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008117 {
8118 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308119
Jeff Johnson295189b2012-06-20 16:38:30 -07008120 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308121
Jeff Johnson295189b2012-06-20 16:38:30 -07008122 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308123 {
8124 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8125 FL("session(%d) old and new heads points to NULL"),
8126 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008127 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308128 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008129
8130 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
8131
8132 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308133 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008134 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008135 return -EINVAL;
8136 }
8137
8138 pAdapter->sessionCtx.ap.beacon = new;
8139
8140 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
8141 }
8142
8143 EXIT();
8144 return status;
8145}
8146
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308147static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
8148 struct net_device *dev,
8149 struct beacon_parameters *params)
8150{
8151 int ret;
8152
8153 vos_ssr_protect(__func__);
8154 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
8155 vos_ssr_unprotect(__func__);
8156
8157 return ret;
8158}
8159
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008160#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8161
8162#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308163static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008164 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008165#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308166static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008167 struct net_device *dev)
8168#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008169{
8170 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07008171 hdd_context_t *pHddCtx = NULL;
8172 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308173 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308174 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008175
8176 ENTER();
8177
8178 if (NULL == pAdapter)
8179 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308180 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07008181 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008182 return -ENODEV;
8183 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008184
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308185 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8186 TRACE_CODE_HDD_CFG80211_STOP_AP,
8187 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308188 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8189 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308190 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008191 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308192 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07008193 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008194
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07008195 pScanInfo = &pHddCtx->scan_info;
8196
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308197 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8198 __func__, hdd_device_modetoString(pAdapter->device_mode),
8199 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008200
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308201 ret = wlan_hdd_scan_abort(pAdapter);
8202
Girish Gowli4bf7a632014-06-12 13:42:11 +05308203 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07008204 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308205 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8206 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308207
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308208 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07008209 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308210 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8211 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08008212
Jeff Johnsone7245742012-09-05 17:12:55 -07008213 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308214 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07008215 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05308216 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07008217 }
8218
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05308219 /* Delete all associated STAs before stopping AP/P2P GO */
8220 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05308221 hdd_hostapd_stop(dev);
8222
Jeff Johnson295189b2012-06-20 16:38:30 -07008223 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008224 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008225 )
8226 {
8227 beacon_data_t *old;
8228
8229 old = pAdapter->sessionCtx.ap.beacon;
8230
8231 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308232 {
8233 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8234 FL("session(%d) beacon data points to NULL"),
8235 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07008236 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308237 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008238
Jeff Johnson295189b2012-06-20 16:38:30 -07008239 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07008240
8241 mutex_lock(&pHddCtx->sap_lock);
8242 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
8243 {
Jeff Johnson4416a782013-03-25 14:17:50 -07008244 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07008245 {
8246 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
8247
8248 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
8249
8250 if (!VOS_IS_STATUS_SUCCESS(status))
8251 {
8252 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008253 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07008254 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308255 }
8256 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008257 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05308258 /* BSS stopped, clear the active sessions for this device mode */
8259 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008260 }
8261 mutex_unlock(&pHddCtx->sap_lock);
8262
8263 if(status != VOS_STATUS_SUCCESS)
8264 {
8265 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008266 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07008267 return -EINVAL;
8268 }
8269
Jeff Johnson4416a782013-03-25 14:17:50 -07008270 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07008271 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
8272 ==eHAL_STATUS_FAILURE)
8273 {
8274 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008275 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008276 }
8277
Jeff Johnson4416a782013-03-25 14:17:50 -07008278 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07008279 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
8280 eANI_BOOLEAN_FALSE) )
8281 {
8282 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008283 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07008284 }
8285
8286 // Reset WNI_CFG_PROBE_RSP Flags
8287 wlan_hdd_reset_prob_rspies(pAdapter);
8288
8289 pAdapter->sessionCtx.ap.beacon = NULL;
8290 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07008291#ifdef WLAN_FEATURE_P2P_DEBUG
8292 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
8293 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
8294 {
8295 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
8296 "GO got removed");
8297 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
8298 }
8299#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008300 }
8301 EXIT();
8302 return status;
8303}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008304
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308305#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8306static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
8307 struct net_device *dev)
8308{
8309 int ret;
8310
8311 vos_ssr_protect(__func__);
8312 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
8313 vos_ssr_unprotect(__func__);
8314
8315 return ret;
8316}
8317#else
8318static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
8319 struct net_device *dev)
8320{
8321 int ret;
8322
8323 vos_ssr_protect(__func__);
8324 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
8325 vos_ssr_unprotect(__func__);
8326
8327 return ret;
8328}
8329#endif
8330
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008331#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
8332
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308333static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308334 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008335 struct cfg80211_ap_settings *params)
8336{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308337 hdd_adapter_t *pAdapter;
8338 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308339 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008340
8341 ENTER();
8342
Girish Gowlib143d7a2015-02-18 19:39:55 +05308343 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008344 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05308346 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308347 return -ENODEV;
8348 }
8349
8350 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8351 if (NULL == pAdapter)
8352 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308353 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308354 "%s: HDD adapter is Null", __func__);
8355 return -ENODEV;
8356 }
8357
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308358 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8359 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
8360 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308361 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
8362 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308363 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308364 "%s: HDD adapter magic is invalid", __func__);
8365 return -ENODEV;
8366 }
8367
8368 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308369 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308370 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308371 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308372 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308373 }
8374
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308375 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
8376 __func__, hdd_device_modetoString(pAdapter->device_mode),
8377 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308378
8379 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008380 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008381 )
8382 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308383 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008384
8385 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308386
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008387 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308388 {
8389 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
8390 FL("already beacon info added to session(%d)"),
8391 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008392 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308393 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008394
Girish Gowlib143d7a2015-02-18 19:39:55 +05308395#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8396 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
8397 &new,
8398 &params->beacon);
8399#else
8400 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
8401 &new,
8402 &params->beacon,
8403 params->dtim_period);
8404#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008405
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308406 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008407 {
8408 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308409 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008410 return -EINVAL;
8411 }
8412 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08008413#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07008414 wlan_hdd_cfg80211_set_channel(wiphy, dev,
8415#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
8416 params->channel, params->channel_type);
8417#else
8418 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
8419#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08008420#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008421 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308422 params->ssid_len, params->hidden_ssid,
8423 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008424 }
8425
8426 EXIT();
8427 return status;
8428}
8429
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308430static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
8431 struct net_device *dev,
8432 struct cfg80211_ap_settings *params)
8433{
8434 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008435
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308436 vos_ssr_protect(__func__);
8437 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
8438 vos_ssr_unprotect(__func__);
8439
8440 return ret;
8441}
8442
8443static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008444 struct net_device *dev,
8445 struct cfg80211_beacon_data *params)
8446{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308447 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308448 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308449 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008450
8451 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308452
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308453 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8454 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
8455 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08008456 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008457 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308458
8459 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8460 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308461 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008462 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308463 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008464 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008465
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308466 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008467 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308468 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008469 {
8470 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308471
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008472 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308473
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008474 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308475 {
8476 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8477 FL("session(%d) beacon data points to NULL"),
8478 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008479 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308480 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008481
8482 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
8483
8484 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308485 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008486 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008487 return -EINVAL;
8488 }
8489
8490 pAdapter->sessionCtx.ap.beacon = new;
8491
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308492 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
8493 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008494 }
8495
8496 EXIT();
8497 return status;
8498}
8499
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308500static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8501 struct net_device *dev,
8502 struct cfg80211_beacon_data *params)
8503{
8504 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008505
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308506 vos_ssr_protect(__func__);
8507 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
8508 vos_ssr_unprotect(__func__);
8509
8510 return ret;
8511}
8512
8513#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008514
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308515static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008516 struct net_device *dev,
8517 struct bss_parameters *params)
8518{
8519 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308520 hdd_context_t *pHddCtx;
8521 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008522
8523 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308524
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308525 if (NULL == pAdapter)
8526 {
8527 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8528 "%s: HDD adapter is Null", __func__);
8529 return -ENODEV;
8530 }
8531 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308532 ret = wlan_hdd_validate_context(pHddCtx);
8533 if (0 != ret)
8534 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308535 return ret;
8536 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308537 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8538 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
8539 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308540 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8541 __func__, hdd_device_modetoString(pAdapter->device_mode),
8542 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008543
8544 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008545 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308546 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008547 {
8548 /* ap_isolate == -1 means that in change bss, upper layer doesn't
8549 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308550 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07008551 {
8552 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308553 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008554 }
8555
8556 EXIT();
8557 return 0;
8558}
8559
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308560static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
8561 struct net_device *dev,
8562 struct bss_parameters *params)
8563{
8564 int ret;
8565
8566 vos_ssr_protect(__func__);
8567 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
8568 vos_ssr_unprotect(__func__);
8569
8570 return ret;
8571}
Kiet Lam10841362013-11-01 11:36:50 +05308572/* FUNCTION: wlan_hdd_change_country_code_cd
8573* to wait for contry code completion
8574*/
8575void* wlan_hdd_change_country_code_cb(void *pAdapter)
8576{
8577 hdd_adapter_t *call_back_pAdapter = pAdapter;
8578 complete(&call_back_pAdapter->change_country_code);
8579 return NULL;
8580}
8581
Jeff Johnson295189b2012-06-20 16:38:30 -07008582/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308583 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07008584 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
8585 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308586int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008587 struct net_device *ndev,
8588 enum nl80211_iftype type,
8589 u32 *flags,
8590 struct vif_params *params
8591 )
8592{
8593 struct wireless_dev *wdev;
8594 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008595 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07008596 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008597 tCsrRoamProfile *pRoamProfile = NULL;
8598 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308599 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008600 eMib_dot11DesiredBssType connectedBssType;
8601 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308602 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008603
8604 ENTER();
8605
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308606 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008607 {
8608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8609 "%s: Adapter context is null", __func__);
8610 return VOS_STATUS_E_FAILURE;
8611 }
8612
8613 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8614 if (!pHddCtx)
8615 {
8616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8617 "%s: HDD context is null", __func__);
8618 return VOS_STATUS_E_FAILURE;
8619 }
8620
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308621 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8622 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
8623 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308624 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308625 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07008626 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308627 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008628 }
8629
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308630 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8631 __func__, hdd_device_modetoString(pAdapter->device_mode),
8632 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008633
Agarwal Ashish51325b52014-06-16 16:50:49 +05308634 if (vos_max_concurrent_connections_reached()) {
8635 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8636 return -EINVAL;
8637 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308638 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07008639 wdev = ndev->ieee80211_ptr;
8640
8641#ifdef WLAN_BTAMP_FEATURE
8642 if((NL80211_IFTYPE_P2P_CLIENT == type)||
8643 (NL80211_IFTYPE_ADHOC == type)||
8644 (NL80211_IFTYPE_AP == type)||
8645 (NL80211_IFTYPE_P2P_GO == type))
8646 {
8647 pHddCtx->isAmpAllowed = VOS_FALSE;
8648 // stop AMP traffic
8649 status = WLANBAP_StopAmp();
8650 if(VOS_STATUS_SUCCESS != status )
8651 {
8652 pHddCtx->isAmpAllowed = VOS_TRUE;
8653 hddLog(VOS_TRACE_LEVEL_FATAL,
8654 "%s: Failed to stop AMP", __func__);
8655 return -EINVAL;
8656 }
8657 }
8658#endif //WLAN_BTAMP_FEATURE
8659 /* Reset the current device mode bit mask*/
8660 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8661
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +05308662 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
8663 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
8664 (type == NL80211_IFTYPE_P2P_GO)))
8665 {
8666 /* Notify Mode change in case of concurrency.
8667 * Below function invokes TDLS teardown Functionality Since TDLS is
8668 * not Supported in case of concurrency i.e Once P2P session
8669 * is detected disable offchannel and teardown TDLS links
8670 */
8671 hddLog(LOG1,
8672 FL("Device mode = %d Interface type = %d"),
8673 pAdapter->device_mode, type);
8674 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
8675 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +05308676
Jeff Johnson295189b2012-06-20 16:38:30 -07008677 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008678 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07008679 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008680 )
8681 {
8682 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008683 if (!pWextState)
8684 {
8685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8686 "%s: pWextState is null", __func__);
8687 return VOS_STATUS_E_FAILURE;
8688 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008689 pRoamProfile = &pWextState->roamProfile;
8690 LastBSSType = pRoamProfile->BSSType;
8691
8692 switch (type)
8693 {
8694 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008695 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008696 hddLog(VOS_TRACE_LEVEL_INFO,
8697 "%s: setting interface Type to INFRASTRUCTURE", __func__);
8698 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008699#ifdef WLAN_FEATURE_11AC
8700 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
8701 {
8702 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
8703 }
8704#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308705 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07008706 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008707 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008708 //Check for sub-string p2p to confirm its a p2p interface
8709 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308710 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +05308711#ifdef FEATURE_WLAN_TDLS
8712 mutex_lock(&pHddCtx->tdls_lock);
8713 wlan_hdd_tdls_exit(pAdapter, TRUE);
8714 mutex_unlock(&pHddCtx->tdls_lock);
8715#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008716 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8717 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8718 }
8719 else
8720 {
8721 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008722 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008723 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008724 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05308725
Jeff Johnson295189b2012-06-20 16:38:30 -07008726 case NL80211_IFTYPE_ADHOC:
8727 hddLog(VOS_TRACE_LEVEL_INFO,
8728 "%s: setting interface Type to ADHOC", __func__);
8729 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
8730 pRoamProfile->phyMode =
8731 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07008732 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008733 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +05308734 hdd_set_ibss_ops( pAdapter );
8735 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +05308736
8737 status = hdd_sta_id_hash_attach(pAdapter);
8738 if (VOS_STATUS_SUCCESS != status) {
8739 hddLog(VOS_TRACE_LEVEL_ERROR,
8740 FL("Failed to initialize hash for IBSS"));
8741 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008742 break;
8743
8744 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008745 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008746 {
8747 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8748 "%s: setting interface Type to %s", __func__,
8749 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
8750
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008751 //Cancel any remain on channel for GO mode
8752 if (NL80211_IFTYPE_P2P_GO == type)
8753 {
8754 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
8755 }
Mohit Khanna0f232092012-09-11 14:46:08 -07008756 if (NL80211_IFTYPE_AP == type)
8757 {
8758 /* As Loading WLAN Driver one interface being created for p2p device
8759 * address. This will take one HW STA and the max number of clients
8760 * that can connect to softAP will be reduced by one. so while changing
8761 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
8762 * interface as it is not required in SoftAP mode.
8763 */
8764
8765 // Get P2P Adapter
8766 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
8767
8768 if (pP2pAdapter)
8769 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308770 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05308771 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07008772 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
8773 }
8774 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05308775 //Disable IMPS & BMPS for SAP/GO
8776 if(VOS_STATUS_E_FAILURE ==
8777 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
8778 {
8779 //Fail to Exit BMPS
8780 VOS_ASSERT(0);
8781 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05308782
8783 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
8784
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308785#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07008786
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308787 /* A Mutex Lock is introduced while changing the mode to
8788 * protect the concurrent access for the Adapters by TDLS
8789 * module.
8790 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308791 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308792#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008793 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05308794 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008795 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07008796 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8797 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308798#ifdef FEATURE_WLAN_TDLS
8799 mutex_unlock(&pHddCtx->tdls_lock);
8800#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008801 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
8802 (pConfig->apRandomBssidEnabled))
8803 {
8804 /* To meet Android requirements create a randomized
8805 MAC address of the form 02:1A:11:Fx:xx:xx */
8806 get_random_bytes(&ndev->dev_addr[3], 3);
8807 ndev->dev_addr[0] = 0x02;
8808 ndev->dev_addr[1] = 0x1A;
8809 ndev->dev_addr[2] = 0x11;
8810 ndev->dev_addr[3] |= 0xF0;
8811 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
8812 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08008813 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
8814 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008815 }
8816
Jeff Johnson295189b2012-06-20 16:38:30 -07008817 hdd_set_ap_ops( pAdapter->dev );
8818
Kiet Lam10841362013-11-01 11:36:50 +05308819 /* This is for only SAP mode where users can
8820 * control country through ini.
8821 * P2P GO follows station country code
8822 * acquired during the STA scanning. */
8823 if((NL80211_IFTYPE_AP == type) &&
8824 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
8825 {
8826 int status = 0;
8827 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
8828 "%s: setting country code from INI ", __func__);
8829 init_completion(&pAdapter->change_country_code);
8830 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
8831 (void *)(tSmeChangeCountryCallback)
8832 wlan_hdd_change_country_code_cb,
8833 pConfig->apCntryCode, pAdapter,
8834 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308835 eSIR_FALSE,
8836 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05308837 if (eHAL_STATUS_SUCCESS == status)
8838 {
8839 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308840 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05308841 &pAdapter->change_country_code,
8842 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308843 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05308844 {
8845 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308846 FL("SME Timed out while setting country code %ld"),
8847 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08008848
8849 if (pHddCtx->isLogpInProgress)
8850 {
8851 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8852 "%s: LOGP in Progress. Ignore!!!", __func__);
8853 return -EAGAIN;
8854 }
Kiet Lam10841362013-11-01 11:36:50 +05308855 }
8856 }
8857 else
8858 {
8859 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008860 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05308861 return -EINVAL;
8862 }
8863 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008864 status = hdd_init_ap_mode(pAdapter);
8865 if(status != VOS_STATUS_SUCCESS)
8866 {
8867 hddLog(VOS_TRACE_LEVEL_FATAL,
8868 "%s: Error initializing the ap mode", __func__);
8869 return -EINVAL;
8870 }
8871 hdd_set_conparam(1);
8872
Nirav Shah7e3c8132015-06-22 23:51:42 +05308873 status = hdd_sta_id_hash_attach(pAdapter);
8874 if (VOS_STATUS_SUCCESS != status)
8875 {
8876 hddLog(VOS_TRACE_LEVEL_ERROR,
8877 FL("Failed to initialize hash for AP"));
8878 return -EINVAL;
8879 }
8880
Jeff Johnson295189b2012-06-20 16:38:30 -07008881 /*interface type changed update in wiphy structure*/
8882 if(wdev)
8883 {
8884 wdev->iftype = type;
8885 pHddCtx->change_iface = type;
8886 }
8887 else
8888 {
8889 hddLog(VOS_TRACE_LEVEL_ERROR,
8890 "%s: ERROR !!!! Wireless dev is NULL", __func__);
8891 return -EINVAL;
8892 }
8893 goto done;
8894 }
8895
8896 default:
8897 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8898 __func__);
8899 return -EOPNOTSUPP;
8900 }
8901 }
8902 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008903 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008904 )
8905 {
8906 switch(type)
8907 {
8908 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008909 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008910 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05308911
8912 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308913#ifdef FEATURE_WLAN_TDLS
8914
8915 /* A Mutex Lock is introduced while changing the mode to
8916 * protect the concurrent access for the Adapters by TDLS
8917 * module.
8918 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308919 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308920#endif
c_hpothu002231a2015-02-05 14:58:51 +05308921 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008922 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008923 //Check for sub-string p2p to confirm its a p2p interface
8924 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008925 {
8926 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8927 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8928 }
8929 else
8930 {
8931 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008932 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008933 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008934 hdd_set_conparam(0);
8935 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008936 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
8937 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308938#ifdef FEATURE_WLAN_TDLS
8939 mutex_unlock(&pHddCtx->tdls_lock);
8940#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308941 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008942 if( VOS_STATUS_SUCCESS != status )
8943 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07008944 /* In case of JB, for P2P-GO, only change interface will be called,
8945 * This is the right place to enable back bmps_imps()
8946 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308947 if (pHddCtx->hdd_wlan_suspended)
8948 {
8949 hdd_set_pwrparams(pHddCtx);
8950 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008951 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008952 goto done;
8953 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008954 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008955 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008956 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8957 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008958 goto done;
8959 default:
8960 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8961 __func__);
8962 return -EOPNOTSUPP;
8963
8964 }
8965
8966 }
8967 else
8968 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308969 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
8970 __func__, hdd_device_modetoString(pAdapter->device_mode),
8971 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008972 return -EOPNOTSUPP;
8973 }
8974
8975
8976 if(pRoamProfile)
8977 {
8978 if ( LastBSSType != pRoamProfile->BSSType )
8979 {
8980 /*interface type changed update in wiphy structure*/
8981 wdev->iftype = type;
8982
8983 /*the BSS mode changed, We need to issue disconnect
8984 if connected or in IBSS disconnect state*/
8985 if ( hdd_connGetConnectedBssType(
8986 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
8987 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
8988 {
8989 /*need to issue a disconnect to CSR.*/
8990 INIT_COMPLETION(pAdapter->disconnect_comp_var);
8991 if( eHAL_STATUS_SUCCESS ==
8992 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
8993 pAdapter->sessionId,
8994 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
8995 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308996 ret = wait_for_completion_interruptible_timeout(
8997 &pAdapter->disconnect_comp_var,
8998 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
8999 if (ret <= 0)
9000 {
9001 hddLog(VOS_TRACE_LEVEL_ERROR,
9002 FL("wait on disconnect_comp_var failed %ld"), ret);
9003 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009004 }
9005 }
9006 }
9007 }
9008
9009done:
9010 /*set bitmask based on updated value*/
9011 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07009012
9013 /* Only STA mode support TM now
9014 * all other mode, TM feature should be disabled */
9015 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
9016 (~VOS_STA & pHddCtx->concurrency_mode) )
9017 {
9018 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
9019 }
9020
Jeff Johnson295189b2012-06-20 16:38:30 -07009021#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309022 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05309023 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07009024 {
9025 //we are ok to do AMP
9026 pHddCtx->isAmpAllowed = VOS_TRUE;
9027 }
9028#endif //WLAN_BTAMP_FEATURE
9029 EXIT();
9030 return 0;
9031}
9032
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05309033/*
9034 * FUNCTION: wlan_hdd_cfg80211_change_iface
9035 * wrapper function to protect the actual implementation from SSR.
9036 */
9037int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
9038 struct net_device *ndev,
9039 enum nl80211_iftype type,
9040 u32 *flags,
9041 struct vif_params *params
9042 )
9043{
9044 int ret;
9045
9046 vos_ssr_protect(__func__);
9047 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
9048 vos_ssr_unprotect(__func__);
9049
9050 return ret;
9051}
9052
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009053#ifdef FEATURE_WLAN_TDLS
9054static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309055 struct net_device *dev,
9056#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
9057 const u8 *mac,
9058#else
9059 u8 *mac,
9060#endif
9061 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009062{
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009063 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009064 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309065 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309066 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05309067 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309068 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009069
9070 ENTER();
9071
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05309072 if (!dev) {
9073 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
9074 return -EINVAL;
9075 }
9076
9077 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
9078 if (!pAdapter) {
9079 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
9080 return -EINVAL;
9081 }
9082
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309083 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009084 {
9085 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9086 "Invalid arguments");
9087 return -EINVAL;
9088 }
Hoonki Lee27511902013-03-14 18:19:06 -07009089
9090 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
9091 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
9092 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309093 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -07009094 "%s: TDLS mode is disabled OR not enabled in FW."
9095 MAC_ADDRESS_STR " Request declined.",
9096 __func__, MAC_ADDR_ARRAY(mac));
9097 return -ENOTSUPP;
9098 }
9099
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009100 if (pHddCtx->isLogpInProgress)
9101 {
9102 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9103 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05309104 wlan_hdd_tdls_set_link_status(pAdapter,
9105 mac,
9106 eTDLS_LINK_IDLE,
9107 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009108 return -EBUSY;
9109 }
9110
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309111 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05309112 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009113
9114 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309115 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009116 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
9117 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309118 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009119 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009120 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05309121 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009122
9123 /* in add station, we accept existing valid staId if there is */
9124 if ((0 == update) &&
9125 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
9126 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009127 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309128 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009129 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009130 " link_status %d. staId %d. add station ignored.",
9131 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
9132 return 0;
9133 }
9134 /* in change station, we accept only when staId is valid */
9135 if ((1 == update) &&
9136 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
9137 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
9138 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309139 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009140 "%s: " MAC_ADDRESS_STR
9141 " link status %d. staId %d. change station %s.",
9142 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
9143 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
9144 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009145 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009146
9147 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +05309148 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009149 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009150 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9151 "%s: " MAC_ADDRESS_STR
9152 " TDLS setup is ongoing. Request declined.",
9153 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07009154 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009155 }
9156
9157 /* first to check if we reached to maximum supported TDLS peer.
9158 TODO: for now, return -EPERM looks working fine,
9159 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309160 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
9161 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009162 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009163 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9164 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05309165 " TDLS Max peer already connected. Request declined."
9166 " Num of peers (%d), Max allowed (%d).",
9167 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
9168 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009169 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009170 }
9171 else
9172 {
9173 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05309174 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009175 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009176 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009177 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9178 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
9179 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009180 return -EPERM;
9181 }
9182 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009183 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05309184 wlan_hdd_tdls_set_link_status(pAdapter,
9185 mac,
9186 eTDLS_LINK_CONNECTING,
9187 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009188
Jeff Johnsond75fe012013-04-06 10:53:06 -07009189 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309190 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009191 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309192 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009193 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07009194 if(StaParams->htcap_present)
9195 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309196 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009197 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009199 "ht_capa->extended_capabilities: %0x",
9200 StaParams->HTCap.extendedHtCapInfo);
9201 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309202 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009203 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309204 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009205 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07009206 if(StaParams->vhtcap_present)
9207 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309208 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07009209 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
9210 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
9211 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
9212 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009213 {
9214 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009215 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009216 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05309217 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009218 "[%d]: %x ", i, StaParams->supported_rates[i]);
9219 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07009220 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05309221 else if ((1 == update) && (NULL == StaParams))
9222 {
9223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9224 "%s : update is true, but staParams is NULL. Error!", __func__);
9225 return -EPERM;
9226 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009227
9228 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
9229
9230 if (!update)
9231 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309232 /*Before adding sta make sure that device exited from BMPS*/
9233 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
9234 {
9235 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9236 "%s: Adding tdls peer sta. Disable BMPS", __func__);
9237 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
9238 if (status != VOS_STATUS_SUCCESS) {
9239 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
9240 }
9241 }
9242
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309243 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009244 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309245 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05309246 hddLog(VOS_TRACE_LEVEL_ERROR,
9247 FL("Failed to add TDLS peer STA. Enable Bmps"));
9248 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309249 return -EPERM;
9250 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009251 }
9252 else
9253 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309254 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009255 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05309256 if (ret != eHAL_STATUS_SUCCESS) {
9257 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
9258 return -EPERM;
9259 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009260 }
9261
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309262 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009263 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
9264
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309265 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009266 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009267 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309268 "%s: timeout waiting for tdls add station indication %ld",
9269 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009270 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009271 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309272
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009273 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
9274 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07009275 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009276 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07009277 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009278 }
9279
9280 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07009281
9282error:
Atul Mittal115287b2014-07-08 13:26:33 +05309283 wlan_hdd_tdls_set_link_status(pAdapter,
9284 mac,
9285 eTDLS_LINK_IDLE,
9286 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07009287 return -EPERM;
9288
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009289}
9290#endif
9291
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309292static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009293 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309294#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
9295 const u8 *mac,
9296#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009297 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309298#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009299 struct station_parameters *params)
9300{
9301 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309302 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309303 hdd_context_t *pHddCtx;
9304 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009305 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309306 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009307#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009308 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009309 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309310 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009311#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009312
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309313 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309314
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05309315 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +05309316 if ((NULL == pAdapter))
9317 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309318 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309319 "invalid adapter ");
9320 return -EINVAL;
9321 }
9322
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309323 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9324 TRACE_CODE_HDD_CHANGE_STATION,
9325 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05309326 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05309327
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309328 ret = wlan_hdd_validate_context(pHddCtx);
9329 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05309330 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309331 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309332 }
9333
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309334 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9335
9336 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009337 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9339 "invalid HDD station context");
9340 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009341 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009342 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
9343
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009344 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
9345 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07009346 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009347 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07009348 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309349 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07009350 WLANTL_STA_AUTHENTICATED);
9351
Gopichand Nakkala29149562013-05-10 21:43:41 +05309352 if (status != VOS_STATUS_SUCCESS)
9353 {
9354 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9355 "%s: Not able to change TL state to AUTHENTICATED", __func__);
9356 return -EINVAL;
9357 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009358 }
9359 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07009360 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
9361 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309362#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009363 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
9364 StaParams.capability = params->capability;
9365 StaParams.uapsd_queues = params->uapsd_queues;
9366 StaParams.max_sp = params->max_sp;
9367
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309368 /* Convert (first channel , number of channels) tuple to
9369 * the total list of channels. This goes with the assumption
9370 * that if the first channel is < 14, then the next channels
9371 * are an incremental of 1 else an incremental of 4 till the number
9372 * of channels.
9373 */
9374 if (0 != params->supported_channels_len) {
9375 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
9376 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
9377 {
9378 int wifi_chan_index;
9379 StaParams.supported_channels[j] = params->supported_channels[i];
9380 wifi_chan_index =
9381 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
9382 no_of_channels = params->supported_channels[i+1];
9383 for(k=1; k <= no_of_channels; k++)
9384 {
9385 StaParams.supported_channels[j+1] =
9386 StaParams.supported_channels[j] + wifi_chan_index;
9387 j+=1;
9388 }
9389 }
9390 StaParams.supported_channels_len = j;
9391 }
9392 vos_mem_copy(StaParams.supported_oper_classes,
9393 params->supported_oper_classes,
9394 params->supported_oper_classes_len);
9395 StaParams.supported_oper_classes_len =
9396 params->supported_oper_classes_len;
9397
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009398 if (0 != params->ext_capab_len)
9399 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
9400 sizeof(StaParams.extn_capability));
9401
9402 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07009403 {
9404 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009405 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07009406 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009407
9408 StaParams.supported_rates_len = params->supported_rates_len;
9409
9410 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
9411 * The supported_rates array , for all the structures propogating till Add Sta
9412 * to the firmware has to be modified , if the supplicant (ieee80211) is
9413 * modified to send more rates.
9414 */
9415
9416 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
9417 */
9418 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
9419 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
9420
9421 if (0 != StaParams.supported_rates_len) {
9422 int i = 0;
9423 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
9424 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009425 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009426 "Supported Rates with Length %d", StaParams.supported_rates_len);
9427 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009428 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009429 "[%d]: %0x", i, StaParams.supported_rates[i]);
9430 }
9431
9432 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07009433 {
9434 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009435 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07009436 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009437
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009438 if (0 != params->ext_capab_len ) {
9439 /*Define A Macro : TODO Sunil*/
9440 if ((1<<4) & StaParams.extn_capability[3]) {
9441 isBufSta = 1;
9442 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309443 /* TDLS Channel Switching Support */
9444 if ((1<<6) & StaParams.extn_capability[3]) {
9445 isOffChannelSupported = 1;
9446 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009447 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309448 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
9449 &StaParams, isBufSta,
9450 isOffChannelSupported);
9451
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309452 if (VOS_STATUS_SUCCESS != status) {
9453 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9454 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
9455 return -EINVAL;
9456 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009457 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
9458
9459 if (VOS_STATUS_SUCCESS != status) {
9460 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9461 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
9462 return -EINVAL;
9463 }
9464 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009465#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05309466 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009467 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009468 return status;
9469}
9470
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309471#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
9472static int wlan_hdd_change_station(struct wiphy *wiphy,
9473 struct net_device *dev,
9474 const u8 *mac,
9475 struct station_parameters *params)
9476#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309477static int wlan_hdd_change_station(struct wiphy *wiphy,
9478 struct net_device *dev,
9479 u8 *mac,
9480 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309481#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309482{
9483 int ret;
9484
9485 vos_ssr_protect(__func__);
9486 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
9487 vos_ssr_unprotect(__func__);
9488
9489 return ret;
9490}
9491
Jeff Johnson295189b2012-06-20 16:38:30 -07009492/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309493 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009494 * This function is used to initialize the key information
9495 */
9496#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309497static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009498 struct net_device *ndev,
9499 u8 key_index, bool pairwise,
9500 const u8 *mac_addr,
9501 struct key_params *params
9502 )
9503#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309504static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009505 struct net_device *ndev,
9506 u8 key_index, const u8 *mac_addr,
9507 struct key_params *params
9508 )
9509#endif
9510{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009511 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07009512 tCsrRoamSetKey setKey;
9513 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309514 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009515 v_U32_t roamId= 0xFF;
9516 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009517 hdd_hostapd_state_t *pHostapdState;
9518 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009519 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309520 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009521
9522 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309523
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309524 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9525 TRACE_CODE_HDD_CFG80211_ADD_KEY,
9526 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309527 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9528 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309529 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009530 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309531 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009532 }
9533
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309534 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9535 __func__, hdd_device_modetoString(pAdapter->device_mode),
9536 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009537
9538 if (CSR_MAX_NUM_KEY <= key_index)
9539 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009540 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009541 key_index);
9542
9543 return -EINVAL;
9544 }
9545
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009546 if (CSR_MAX_KEY_LEN < params->key_len)
9547 {
9548 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
9549 params->key_len);
9550
9551 return -EINVAL;
9552 }
9553
9554 hddLog(VOS_TRACE_LEVEL_INFO,
9555 "%s: called with key index = %d & key length %d",
9556 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009557
9558 /*extract key idx, key len and key*/
9559 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9560 setKey.keyId = key_index;
9561 setKey.keyLength = params->key_len;
9562 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
9563
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009564 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009565 {
9566 case WLAN_CIPHER_SUITE_WEP40:
9567 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
9568 break;
9569
9570 case WLAN_CIPHER_SUITE_WEP104:
9571 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
9572 break;
9573
9574 case WLAN_CIPHER_SUITE_TKIP:
9575 {
9576 u8 *pKey = &setKey.Key[0];
9577 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
9578
9579 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
9580
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009581 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07009582
9583 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009584 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009585 |--------------|----------|----------|
9586 <---16bytes---><--8bytes--><--8bytes-->
9587
9588 */
9589 /*Sme expects the 32 bytes key to be in the below order
9590
9591 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009592 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009593 |--------------|----------|----------|
9594 <---16bytes---><--8bytes--><--8bytes-->
9595 */
9596 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009597 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07009598
9599 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009600 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009601
9602 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009603 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009604
9605
9606 break;
9607 }
9608
9609 case WLAN_CIPHER_SUITE_CCMP:
9610 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
9611 break;
9612
9613#ifdef FEATURE_WLAN_WAPI
9614 case WLAN_CIPHER_SUITE_SMS4:
9615 {
9616 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9617 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
9618 params->key, params->key_len);
9619 return 0;
9620 }
9621#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009622
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009623#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009624 case WLAN_CIPHER_SUITE_KRK:
9625 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
9626 break;
9627#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009628
9629#ifdef WLAN_FEATURE_11W
9630 case WLAN_CIPHER_SUITE_AES_CMAC:
9631 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07009632 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07009633#endif
9634
Jeff Johnson295189b2012-06-20 16:38:30 -07009635 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009636 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009637 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309638 status = -EOPNOTSUPP;
9639 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009640 }
9641
9642 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
9643 __func__, setKey.encType);
9644
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009645 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07009646#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9647 (!pairwise)
9648#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009649 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07009650#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009651 )
9652 {
9653 /* set group key*/
9654 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9655 "%s- %d: setting Broadcast key",
9656 __func__, __LINE__);
9657 setKey.keyDirection = eSIR_RX_ONLY;
9658 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9659 }
9660 else
9661 {
9662 /* set pairwise key*/
9663 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9664 "%s- %d: setting pairwise key",
9665 __func__, __LINE__);
9666 setKey.keyDirection = eSIR_TX_RX;
9667 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9668 }
9669 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
9670 {
9671 setKey.keyDirection = eSIR_TX_RX;
9672 /*Set the group key*/
9673 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9674 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07009675
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009676 if ( 0 != status )
9677 {
9678 hddLog(VOS_TRACE_LEVEL_ERROR,
9679 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309680 status = -EINVAL;
9681 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009682 }
9683 /*Save the keys here and call sme_RoamSetKey for setting
9684 the PTK after peer joins the IBSS network*/
9685 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
9686 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309687 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009688 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05309689 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
9690 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
9691 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009692 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009693 if( pHostapdState->bssState == BSS_START )
9694 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009695 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9696 vos_status = wlan_hdd_check_ula_done(pAdapter);
9697
9698 if ( vos_status != VOS_STATUS_SUCCESS )
9699 {
9700 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9701 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9702 __LINE__, vos_status );
9703
9704 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9705
9706 status = -EINVAL;
9707 goto end;
9708 }
9709
Jeff Johnson295189b2012-06-20 16:38:30 -07009710 status = WLANSAP_SetKeySta( pVosContext, &setKey);
9711
9712 if ( status != eHAL_STATUS_SUCCESS )
9713 {
9714 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9715 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9716 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309717 status = -EINVAL;
9718 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009719 }
9720 }
9721
9722 /* Saving WEP keys */
9723 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
9724 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
9725 {
9726 //Save the wep key in ap context. Issue setkey after the BSS is started.
9727 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9728 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
9729 }
9730 else
9731 {
9732 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009733 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009734 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
9735 }
9736 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009737 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
9738 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009739 {
9740 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9741 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9742
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309743#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9744 if (!pairwise)
9745#else
9746 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9747#endif
9748 {
9749 /* set group key*/
9750 if (pHddStaCtx->roam_info.deferKeyComplete)
9751 {
9752 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9753 "%s- %d: Perform Set key Complete",
9754 __func__, __LINE__);
9755 hdd_PerformRoamSetKeyComplete(pAdapter);
9756 }
9757 }
9758
Jeff Johnson295189b2012-06-20 16:38:30 -07009759 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
9760
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08009761 pWextState->roamProfile.Keys.defaultIndex = key_index;
9762
9763
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009764 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009765 params->key, params->key_len);
9766
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309767
Jeff Johnson295189b2012-06-20 16:38:30 -07009768 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9769
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309770 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009771 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309772 __func__, setKey.peerMac[0], setKey.peerMac[1],
9773 setKey.peerMac[2], setKey.peerMac[3],
9774 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009775 setKey.keyDirection);
9776
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009777 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +05309778
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009779 if ( vos_status != VOS_STATUS_SUCCESS )
9780 {
9781 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009782 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9783 __LINE__, vos_status );
9784
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009785 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009786
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009787 status = -EINVAL;
9788 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009789
9790 }
9791
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009792#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309793 /* The supplicant may attempt to set the PTK once pre-authentication
9794 is done. Save the key in the UMAC and include it in the ADD BSS
9795 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009796 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309797 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009798 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309799 hddLog(VOS_TRACE_LEVEL_INFO_MED,
9800 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309801 status = 0;
9802 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309803 }
9804 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
9805 {
9806 hddLog(VOS_TRACE_LEVEL_ERROR,
9807 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309808 status = -EINVAL;
9809 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009810 }
9811#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07009812
9813 /* issue set key request to SME*/
9814 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9815 pAdapter->sessionId, &setKey, &roamId );
9816
9817 if ( 0 != status )
9818 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309819 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009820 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
9821 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309822 status = -EINVAL;
9823 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009824 }
9825
9826
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309827 /* in case of IBSS as there was no information available about WEP keys during
9828 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07009829 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309830 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
9831 !( ( IW_AUTH_KEY_MGMT_802_1X
9832 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07009833 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
9834 )
9835 &&
9836 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
9837 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
9838 )
9839 )
9840 {
9841 setKey.keyDirection = eSIR_RX_ONLY;
9842 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9843
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309844 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009845 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309846 __func__, setKey.peerMac[0], setKey.peerMac[1],
9847 setKey.peerMac[2], setKey.peerMac[3],
9848 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009849 setKey.keyDirection);
9850
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309851 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009852 pAdapter->sessionId, &setKey, &roamId );
9853
9854 if ( 0 != status )
9855 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309856 hddLog(VOS_TRACE_LEVEL_ERROR,
9857 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009858 __func__, status);
9859 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309860 status = -EINVAL;
9861 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009862 }
9863 }
9864 }
9865
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309866end:
9867 /* Need to clear any trace of key value in the memory.
9868 * Thus zero out the memory even though it is local
9869 * variable.
9870 */
9871 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309872 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309873 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009874}
9875
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309876#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9877static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9878 struct net_device *ndev,
9879 u8 key_index, bool pairwise,
9880 const u8 *mac_addr,
9881 struct key_params *params
9882 )
9883#else
9884static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9885 struct net_device *ndev,
9886 u8 key_index, const u8 *mac_addr,
9887 struct key_params *params
9888 )
9889#endif
9890{
9891 int ret;
9892 vos_ssr_protect(__func__);
9893#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9894 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
9895 mac_addr, params);
9896#else
9897 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
9898 params);
9899#endif
9900 vos_ssr_unprotect(__func__);
9901
9902 return ret;
9903}
9904
Jeff Johnson295189b2012-06-20 16:38:30 -07009905/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309906 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009907 * This function is used to get the key information
9908 */
9909#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309910static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309911 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009912 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309913 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009914 const u8 *mac_addr, void *cookie,
9915 void (*callback)(void *cookie, struct key_params*)
9916 )
9917#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309918static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309919 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009920 struct net_device *ndev,
9921 u8 key_index, const u8 *mac_addr, void *cookie,
9922 void (*callback)(void *cookie, struct key_params*)
9923 )
9924#endif
9925{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309926 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309927 hdd_wext_state_t *pWextState = NULL;
9928 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009929 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309930 hdd_context_t *pHddCtx;
9931 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009932
9933 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309934
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309935 if (NULL == pAdapter)
9936 {
9937 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9938 "%s: HDD adapter is Null", __func__);
9939 return -ENODEV;
9940 }
9941
9942 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9943 ret = wlan_hdd_validate_context(pHddCtx);
9944 if (0 != ret)
9945 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309946 return ret;
9947 }
9948
9949 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9950 pRoamProfile = &(pWextState->roamProfile);
9951
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309952 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9953 __func__, hdd_device_modetoString(pAdapter->device_mode),
9954 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309955
Jeff Johnson295189b2012-06-20 16:38:30 -07009956 memset(&params, 0, sizeof(params));
9957
9958 if (CSR_MAX_NUM_KEY <= key_index)
9959 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309960 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07009961 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309962 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009963
9964 switch(pRoamProfile->EncryptionType.encryptionType[0])
9965 {
9966 case eCSR_ENCRYPT_TYPE_NONE:
9967 params.cipher = IW_AUTH_CIPHER_NONE;
9968 break;
9969
9970 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
9971 case eCSR_ENCRYPT_TYPE_WEP40:
9972 params.cipher = WLAN_CIPHER_SUITE_WEP40;
9973 break;
9974
9975 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
9976 case eCSR_ENCRYPT_TYPE_WEP104:
9977 params.cipher = WLAN_CIPHER_SUITE_WEP104;
9978 break;
9979
9980 case eCSR_ENCRYPT_TYPE_TKIP:
9981 params.cipher = WLAN_CIPHER_SUITE_TKIP;
9982 break;
9983
9984 case eCSR_ENCRYPT_TYPE_AES:
9985 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
9986 break;
9987
9988 default:
9989 params.cipher = IW_AUTH_CIPHER_NONE;
9990 break;
9991 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309992
c_hpothuaaf19692014-05-17 17:01:48 +05309993 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9994 TRACE_CODE_HDD_CFG80211_GET_KEY,
9995 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309996
Jeff Johnson295189b2012-06-20 16:38:30 -07009997 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
9998 params.seq_len = 0;
9999 params.seq = NULL;
10000 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
10001 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010002 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010003 return 0;
10004}
10005
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010006#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10007static int wlan_hdd_cfg80211_get_key(
10008 struct wiphy *wiphy,
10009 struct net_device *ndev,
10010 u8 key_index, bool pairwise,
10011 const u8 *mac_addr, void *cookie,
10012 void (*callback)(void *cookie, struct key_params*)
10013 )
10014#else
10015static int wlan_hdd_cfg80211_get_key(
10016 struct wiphy *wiphy,
10017 struct net_device *ndev,
10018 u8 key_index, const u8 *mac_addr, void *cookie,
10019 void (*callback)(void *cookie, struct key_params*)
10020 )
10021#endif
10022{
10023 int ret;
10024
10025 vos_ssr_protect(__func__);
10026#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10027 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
10028 mac_addr, cookie, callback);
10029#else
10030 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
10031 callback);
10032#endif
10033 vos_ssr_unprotect(__func__);
10034
10035 return ret;
10036}
10037
Jeff Johnson295189b2012-06-20 16:38:30 -070010038/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010039 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010040 * This function is used to delete the key information
10041 */
10042#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010043static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010044 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010045 u8 key_index,
10046 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -070010047 const u8 *mac_addr
10048 )
10049#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010050static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010051 struct net_device *ndev,
10052 u8 key_index,
10053 const u8 *mac_addr
10054 )
10055#endif
10056{
10057 int status = 0;
10058
10059 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010060 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -070010061 //it is observed that this is invalidating peer
10062 //key index whenever re-key is done. This is affecting data link.
10063 //It should be ok to ignore del_key.
10064#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010065 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
10066 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -070010067 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
10068 tCsrRoamSetKey setKey;
10069 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010070
Jeff Johnson295189b2012-06-20 16:38:30 -070010071 ENTER();
10072
10073 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
10074 __func__,pAdapter->device_mode);
10075
10076 if (CSR_MAX_NUM_KEY <= key_index)
10077 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010078 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010079 key_index);
10080
10081 return -EINVAL;
10082 }
10083
10084 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
10085 setKey.keyId = key_index;
10086
10087 if (mac_addr)
10088 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
10089 else
10090 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
10091
10092 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
10093
10094 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010095 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010096 )
10097 {
10098
10099 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -070010100 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
10101 if( pHostapdState->bssState == BSS_START)
10102 {
10103 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010104
Jeff Johnson295189b2012-06-20 16:38:30 -070010105 if ( status != eHAL_STATUS_SUCCESS )
10106 {
10107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10108 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
10109 __LINE__, status );
10110 }
10111 }
10112 }
10113 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010114 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -070010115 )
10116 {
10117 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10118
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010119 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
10120
10121 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -070010122 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010123 __func__, setKey.peerMac[0], setKey.peerMac[1],
10124 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -070010125 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010126 if(pAdapter->sessionCtx.station.conn_info.connState ==
10127 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -070010128 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010129 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010130 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010131
Jeff Johnson295189b2012-06-20 16:38:30 -070010132 if ( 0 != status )
10133 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010134 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010135 "%s: sme_RoamSetKey failure, returned %d",
10136 __func__, status);
10137 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
10138 return -EINVAL;
10139 }
10140 }
10141 }
10142#endif
Jeff Johnsone7245742012-09-05 17:12:55 -070010143 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010144 return status;
10145}
10146
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053010147#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10148static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
10149 struct net_device *ndev,
10150 u8 key_index,
10151 bool pairwise,
10152 const u8 *mac_addr
10153 )
10154#else
10155static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
10156 struct net_device *ndev,
10157 u8 key_index,
10158 const u8 *mac_addr
10159 )
10160#endif
10161{
10162 int ret;
10163
10164 vos_ssr_protect(__func__);
10165#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10166 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
10167 mac_addr);
10168#else
10169 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
10170#endif
10171 vos_ssr_unprotect(__func__);
10172
10173 return ret;
10174}
10175
Jeff Johnson295189b2012-06-20 16:38:30 -070010176/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010177 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -070010178 * This function is used to set the default tx key index
10179 */
10180#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010181static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010182 struct net_device *ndev,
10183 u8 key_index,
10184 bool unicast, bool multicast)
10185#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010186static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010187 struct net_device *ndev,
10188 u8 key_index)
10189#endif
10190{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010191 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010192 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +053010193 hdd_wext_state_t *pWextState;
10194 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010195 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010196
10197 ENTER();
10198
Gopichand Nakkala29149562013-05-10 21:43:41 +053010199 if ((NULL == pAdapter))
10200 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010201 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +053010202 "invalid adapter");
10203 return -EINVAL;
10204 }
10205
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010206 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10207 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
10208 pAdapter->sessionId, key_index));
10209
Gopichand Nakkala29149562013-05-10 21:43:41 +053010210 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10211 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10212
10213 if ((NULL == pWextState) || (NULL == pHddStaCtx))
10214 {
10215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10216 "invalid Wext state or HDD context");
10217 return -EINVAL;
10218 }
10219
Arif Hussain6d2a3322013-11-17 19:50:10 -080010220 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010221 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010222
Jeff Johnson295189b2012-06-20 16:38:30 -070010223 if (CSR_MAX_NUM_KEY <= key_index)
10224 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010225 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010226 key_index);
10227
10228 return -EINVAL;
10229 }
10230
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010231 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10232 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010233 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010234 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010235 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010236 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010237
Jeff Johnson295189b2012-06-20 16:38:30 -070010238 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -070010239 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010240 )
Jeff Johnson295189b2012-06-20 16:38:30 -070010241 {
Gopichand Nakkala29149562013-05-10 21:43:41 +053010242 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -080010243 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010244 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -080010245 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -070010246 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010247 {
10248 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -070010249 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010250
Jeff Johnson295189b2012-06-20 16:38:30 -070010251 tCsrRoamSetKey setKey;
10252 v_U32_t roamId= 0xFF;
10253 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010254
10255 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010256 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010257
Jeff Johnson295189b2012-06-20 16:38:30 -070010258 Keys->defaultIndex = (u8)key_index;
10259 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
10260 setKey.keyId = key_index;
10261 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010262
10263 vos_mem_copy(&setKey.Key[0],
10264 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070010265 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010266
Gopichand Nakkala29149562013-05-10 21:43:41 +053010267 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010268
10269 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -070010270 &pHddStaCtx->conn_info.bssId[0],
10271 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010272
Gopichand Nakkala29149562013-05-10 21:43:41 +053010273 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
10274 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
10275 eCSR_ENCRYPT_TYPE_WEP104)
10276 {
10277 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
10278 even though ap is configured for WEP-40 encryption. In this canse the key length
10279 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
10280 type(104) and switching encryption type to 40*/
10281 pWextState->roamProfile.EncryptionType.encryptionType[0] =
10282 eCSR_ENCRYPT_TYPE_WEP40;
10283 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
10284 eCSR_ENCRYPT_TYPE_WEP40;
10285 }
10286
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010287 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -070010288 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010289
Jeff Johnson295189b2012-06-20 16:38:30 -070010290 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010291 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070010292 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010293
Jeff Johnson295189b2012-06-20 16:38:30 -070010294 if ( 0 != status )
10295 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010296 hddLog(VOS_TRACE_LEVEL_ERROR,
10297 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070010298 status);
10299 return -EINVAL;
10300 }
10301 }
10302 }
10303
10304 /* In SoftAp mode setting key direction for default mode */
10305 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
10306 {
10307 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
10308 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
10309 (eCSR_ENCRYPT_TYPE_AES !=
10310 pWextState->roamProfile.EncryptionType.encryptionType[0])
10311 )
10312 {
10313 /* Saving key direction for default key index to TX default */
10314 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
10315 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
10316 }
10317 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010318 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010319 return status;
10320}
10321
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +053010322#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10323static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
10324 struct net_device *ndev,
10325 u8 key_index,
10326 bool unicast, bool multicast)
10327#else
10328static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
10329 struct net_device *ndev,
10330 u8 key_index)
10331#endif
10332{
10333 int ret;
10334 vos_ssr_protect(__func__);
10335#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10336 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
10337 multicast);
10338#else
10339 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
10340#endif
10341 vos_ssr_unprotect(__func__);
10342
10343 return ret;
10344}
10345
Jeff Johnson295189b2012-06-20 16:38:30 -070010346/*
10347 * FUNCTION: wlan_hdd_cfg80211_inform_bss
10348 * This function is used to inform the BSS details to nl80211 interface.
10349 */
10350static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
10351 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
10352{
10353 struct net_device *dev = pAdapter->dev;
10354 struct wireless_dev *wdev = dev->ieee80211_ptr;
10355 struct wiphy *wiphy = wdev->wiphy;
10356 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
10357 int chan_no;
10358 int ie_length;
10359 const char *ie;
10360 unsigned int freq;
10361 struct ieee80211_channel *chan;
10362 int rssi = 0;
10363 struct cfg80211_bss *bss = NULL;
10364
Jeff Johnson295189b2012-06-20 16:38:30 -070010365 if( NULL == pBssDesc )
10366 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010367 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010368 return bss;
10369 }
10370
10371 chan_no = pBssDesc->channelId;
10372 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
10373 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
10374
10375 if( NULL == ie )
10376 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010377 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010378 return bss;
10379 }
10380
10381#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10382 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10383 {
10384 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10385 }
10386 else
10387 {
10388 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10389 }
10390#else
10391 freq = ieee80211_channel_to_frequency(chan_no);
10392#endif
10393
10394 chan = __ieee80211_get_channel(wiphy, freq);
10395
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053010396 if (!chan) {
10397 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
10398 return NULL;
10399 }
10400
Abhishek Singhaee43942014-06-16 18:55:47 +053010401 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070010402
Anand N Sunkad9f80b742015-07-30 20:05:51 +053010403 return cfg80211_inform_bss(wiphy, chan,
10404#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10405 CFG80211_BSS_FTYPE_UNKNOWN,
10406#endif
10407 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010408 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070010409 pBssDesc->capabilityInfo,
10410 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053010411 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070010412}
10413
10414
10415
10416/*
10417 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
10418 * This function is used to inform the BSS details to nl80211 interface.
10419 */
10420struct cfg80211_bss*
10421wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
10422 tSirBssDescription *bss_desc
10423 )
10424{
10425 /*
10426 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
10427 already exists in bss data base of cfg80211 for that particular BSS ID.
10428 Using cfg80211_inform_bss_frame to update the bss entry instead of
10429 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
10430 now there is no possibility to get the mgmt(probe response) frame from PE,
10431 converting bss_desc to ieee80211_mgmt(probe response) and passing to
10432 cfg80211_inform_bss_frame.
10433 */
10434 struct net_device *dev = pAdapter->dev;
10435 struct wireless_dev *wdev = dev->ieee80211_ptr;
10436 struct wiphy *wiphy = wdev->wiphy;
10437 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010438#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
10439 qcom_ie_age *qie_age = NULL;
10440 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
10441#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010442 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010443#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010444 const char *ie =
10445 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
10446 unsigned int freq;
10447 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053010448 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010449 struct cfg80211_bss *bss_status = NULL;
10450 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
10451 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070010452 hdd_context_t *pHddCtx;
10453 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070010454#ifdef WLAN_OPEN_SOURCE
10455 struct timespec ts;
10456#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010457
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010458
Wilson Yangf80a0542013-10-07 13:02:37 -070010459 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10460 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070010461 if (0 != status)
10462 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070010463 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010464 }
10465
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053010466 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070010467 if (!mgmt)
10468 {
10469 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10470 "%s: memory allocation failed ", __func__);
10471 return NULL;
10472 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070010473
Jeff Johnson295189b2012-06-20 16:38:30 -070010474 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070010475
10476#ifdef WLAN_OPEN_SOURCE
10477 /* Android does not want the timestamp from the frame.
10478 Instead it wants a monotonic increasing value */
10479 get_monotonic_boottime(&ts);
10480 mgmt->u.probe_resp.timestamp =
10481 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
10482#else
10483 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070010484 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
10485 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070010486
10487#endif
10488
Jeff Johnson295189b2012-06-20 16:38:30 -070010489 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
10490 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010491
10492#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
10493 /* GPS Requirement: need age ie per entry. Using vendor specific. */
10494 /* Assuming this is the last IE, copy at the end */
10495 ie_length -=sizeof(qcom_ie_age);
10496 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
10497 qie_age->element_id = QCOM_VENDOR_IE_ID;
10498 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
10499 qie_age->oui_1 = QCOM_OUI1;
10500 qie_age->oui_2 = QCOM_OUI2;
10501 qie_age->oui_3 = QCOM_OUI3;
10502 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
10503 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
10504#endif
10505
Jeff Johnson295189b2012-06-20 16:38:30 -070010506 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053010507 if (bss_desc->fProbeRsp)
10508 {
10509 mgmt->frame_control |=
10510 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
10511 }
10512 else
10513 {
10514 mgmt->frame_control |=
10515 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
10516 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010517
10518#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010519 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010520 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
10521 {
10522 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10523 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010524 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010525 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
10526
10527 {
10528 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10529 }
10530 else
10531 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010532 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
10533 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070010534 kfree(mgmt);
10535 return NULL;
10536 }
10537#else
10538 freq = ieee80211_channel_to_frequency(chan_no);
10539#endif
10540 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010541 /*when the band is changed on the fly using the GUI, three things are done
10542 * 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)
10543 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
10544 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
10545 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
10546 * and discards the channels correponding to previous band and calls back with zero bss results.
10547 * 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
10548 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
10549 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
10550 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
10551 * So drop the bss and continue to next bss.
10552 */
10553 if(chan == NULL)
10554 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010555 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070010556 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010557 return NULL;
10558 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053010559 /*To keep the rssi icon of the connected AP in the scan window
10560 *and the rssi icon of the wireless networks in sync
10561 * */
10562 if (( eConnectionState_Associated ==
10563 pAdapter->sessionCtx.station.conn_info.connState ) &&
10564 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
10565 pAdapter->sessionCtx.station.conn_info.bssId,
10566 WNI_CFG_BSSID_LEN)) &&
10567 (pHddCtx->hdd_wlan_suspended == FALSE))
10568 {
10569 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
10570 rssi = (pAdapter->rssi * 100);
10571 }
10572 else
10573 {
10574 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
10575 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010576
Nirav Shah20ac06f2013-12-12 18:14:06 +053010577 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053010578 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
10579 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053010580
Jeff Johnson295189b2012-06-20 16:38:30 -070010581 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
10582 frame_len, rssi, GFP_KERNEL);
10583 kfree(mgmt);
10584 return bss_status;
10585}
10586
10587/*
10588 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
10589 * This function is used to update the BSS data base of CFG8011
10590 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010591struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010592 tCsrRoamInfo *pRoamInfo
10593 )
10594{
10595 tCsrRoamConnectedProfile roamProfile;
10596 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10597 struct cfg80211_bss *bss = NULL;
10598
10599 ENTER();
10600
10601 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
10602 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
10603
10604 if (NULL != roamProfile.pBssDesc)
10605 {
Girish Gowlif4b68022014-08-28 23:18:57 +053010606 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10607 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070010608
10609 if (NULL == bss)
10610 {
10611 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
10612 __func__);
10613 }
10614
10615 sme_RoamFreeConnectProfile(hHal, &roamProfile);
10616 }
10617 else
10618 {
10619 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
10620 __func__);
10621 }
10622 return bss;
10623}
10624
10625/*
10626 * FUNCTION: wlan_hdd_cfg80211_update_bss
10627 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010628static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
10629 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070010630 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010631{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010632 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010633 tCsrScanResultInfo *pScanResult;
10634 eHalStatus status = 0;
10635 tScanResultHandle pResult;
10636 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010637 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010638 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070010639 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010640
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010641 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10642 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
10643 NO_SESSION, pAdapter->sessionId));
10644
Wilson Yangf80a0542013-10-07 13:02:37 -070010645 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10646
10647 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070010648 {
Wilson Yangf80a0542013-10-07 13:02:37 -070010649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10650 "%s:LOGP in Progress. Ignore!!!",__func__);
10651 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010652 }
10653
Wilson Yangf80a0542013-10-07 13:02:37 -070010654
10655 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053010656 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070010657 {
10658 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10659 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
10660 return VOS_STATUS_E_PERM;
10661 }
10662
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010663 if (pAdapter->request != NULL)
10664 {
10665 if ((pAdapter->request->n_ssids == 1)
10666 && (pAdapter->request->ssids != NULL)
10667 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
10668 is_p2p_scan = true;
10669 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010670 /*
10671 * start getting scan results and populate cgf80211 BSS database
10672 */
10673 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
10674
10675 /* no scan results */
10676 if (NULL == pResult)
10677 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010678 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
10679 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053010680 wlan_hdd_get_frame_logs(pAdapter,
10681 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070010682 return status;
10683 }
10684
10685 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
10686
10687 while (pScanResult)
10688 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010689 /*
10690 * cfg80211_inform_bss() is not updating ie field of bss entry, if
10691 * entry already exists in bss data base of cfg80211 for that
10692 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
10693 * bss entry instead of cfg80211_inform_bss, But this call expects
10694 * mgmt packet as input. As of now there is no possibility to get
10695 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070010696 * ieee80211_mgmt(probe response) and passing to c
10697 * fg80211_inform_bss_frame.
10698 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010699 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
10700 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
10701 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010702 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10703 continue; //Skip the non p2p bss entries
10704 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010705 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10706 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010707
Jeff Johnson295189b2012-06-20 16:38:30 -070010708
10709 if (NULL == bss_status)
10710 {
10711 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010712 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010713 }
10714 else
10715 {
Yue Maf49ba872013-08-19 12:04:25 -070010716 cfg80211_put_bss(
10717#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
10718 wiphy,
10719#endif
10720 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010721 }
10722
10723 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10724 }
10725
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010726 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010727 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010728 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010729}
10730
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010731void
10732hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
10733{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010734 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080010735 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010736} /****** end hddPrintMacAddr() ******/
10737
10738void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010739hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010740{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010741 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010742 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010743 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
10744 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
10745 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010746} /****** end hddPrintPmkId() ******/
10747
10748//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
10749//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
10750
10751//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
10752//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
10753
10754#define dump_bssid(bssid) \
10755 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010756 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
10757 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010758 }
10759
10760#define dump_pmkid(pMac, pmkid) \
10761 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010762 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
10763 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010764 }
10765
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070010766#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010767/*
10768 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
10769 * This function is used to notify the supplicant of a new PMKSA candidate.
10770 */
10771int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010772 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010773 int index, bool preauth )
10774{
Jeff Johnsone7245742012-09-05 17:12:55 -070010775#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010776 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010777 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010778
10779 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070010780 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010781
10782 if( NULL == pRoamInfo )
10783 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010784 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010785 return -EINVAL;
10786 }
10787
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010788 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
10789 {
10790 dump_bssid(pRoamInfo->bssid);
10791 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010792 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010793 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010794#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010795 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010796}
10797#endif //FEATURE_WLAN_LFR
10798
Yue Maef608272013-04-08 23:09:17 -070010799#ifdef FEATURE_WLAN_LFR_METRICS
10800/*
10801 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
10802 * 802.11r/LFR metrics reporting function to report preauth initiation
10803 *
10804 */
10805#define MAX_LFR_METRICS_EVENT_LENGTH 100
10806VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
10807 tCsrRoamInfo *pRoamInfo)
10808{
10809 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10810 union iwreq_data wrqu;
10811
10812 ENTER();
10813
10814 if (NULL == pAdapter)
10815 {
10816 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10817 return VOS_STATUS_E_FAILURE;
10818 }
10819
10820 /* create the event */
10821 memset(&wrqu, 0, sizeof(wrqu));
10822 memset(metrics_notification, 0, sizeof(metrics_notification));
10823
10824 wrqu.data.pointer = metrics_notification;
10825 wrqu.data.length = scnprintf(metrics_notification,
10826 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
10827 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10828
10829 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10830
10831 EXIT();
10832
10833 return VOS_STATUS_SUCCESS;
10834}
10835
10836/*
10837 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
10838 * 802.11r/LFR metrics reporting function to report preauth completion
10839 * or failure
10840 */
10841VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
10842 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
10843{
10844 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10845 union iwreq_data wrqu;
10846
10847 ENTER();
10848
10849 if (NULL == pAdapter)
10850 {
10851 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10852 return VOS_STATUS_E_FAILURE;
10853 }
10854
10855 /* create the event */
10856 memset(&wrqu, 0, sizeof(wrqu));
10857 memset(metrics_notification, 0, sizeof(metrics_notification));
10858
10859 scnprintf(metrics_notification, sizeof(metrics_notification),
10860 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
10861 MAC_ADDR_ARRAY(pRoamInfo->bssid));
10862
10863 if (1 == preauth_status)
10864 strncat(metrics_notification, " TRUE", 5);
10865 else
10866 strncat(metrics_notification, " FALSE", 6);
10867
10868 wrqu.data.pointer = metrics_notification;
10869 wrqu.data.length = strlen(metrics_notification);
10870
10871 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10872
10873 EXIT();
10874
10875 return VOS_STATUS_SUCCESS;
10876}
10877
10878/*
10879 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
10880 * 802.11r/LFR metrics reporting function to report handover initiation
10881 *
10882 */
10883VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
10884 tCsrRoamInfo *pRoamInfo)
10885{
10886 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10887 union iwreq_data wrqu;
10888
10889 ENTER();
10890
10891 if (NULL == pAdapter)
10892 {
10893 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10894 return VOS_STATUS_E_FAILURE;
10895 }
10896
10897 /* create the event */
10898 memset(&wrqu, 0, sizeof(wrqu));
10899 memset(metrics_notification, 0, sizeof(metrics_notification));
10900
10901 wrqu.data.pointer = metrics_notification;
10902 wrqu.data.length = scnprintf(metrics_notification,
10903 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
10904 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10905
10906 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10907
10908 EXIT();
10909
10910 return VOS_STATUS_SUCCESS;
10911}
10912#endif
10913
Jeff Johnson295189b2012-06-20 16:38:30 -070010914/*
10915 * FUNCTION: hdd_cfg80211_scan_done_callback
10916 * scanning callback function, called after finishing scan
10917 *
10918 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010919static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070010920 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
10921{
10922 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010923 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070010924 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010925 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010926 struct cfg80211_scan_request *req = NULL;
10927 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010928 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010929 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010930 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010931 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010932
10933 ENTER();
10934
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010935 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053010936 if (NULL == pHddCtx) {
10937 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010938 goto allow_suspend;
10939 }
10940
10941 pScanInfo = &pHddCtx->scan_info;
10942
Jeff Johnson295189b2012-06-20 16:38:30 -070010943 hddLog(VOS_TRACE_LEVEL_INFO,
10944 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080010945 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010946 __func__, halHandle, pContext, (int) scanId, (int) status);
10947
Kiet Lamac06e2c2013-10-23 16:25:07 +053010948 pScanInfo->mScanPendingCounter = 0;
10949
Jeff Johnson295189b2012-06-20 16:38:30 -070010950 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010951 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070010952 &pScanInfo->scan_req_completion_event,
10953 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010954 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070010955 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010956 hddLog(VOS_TRACE_LEVEL_ERROR,
10957 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070010958 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010959 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010960 }
10961
Yue Maef608272013-04-08 23:09:17 -070010962 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010963 {
10964 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010965 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010966 }
10967
10968 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010969 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070010970 {
10971 hddLog(VOS_TRACE_LEVEL_INFO,
10972 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010973 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070010974 (int) scanId);
10975 }
10976
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010977 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010978 pAdapter);
10979
10980 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010981 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010982
10983
10984 /* If any client wait scan result through WEXT
10985 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010986 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070010987 {
10988 /* The other scan request waiting for current scan finish
10989 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010990 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010991 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010992 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070010993 }
10994 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010995 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010996 {
10997 struct net_device *dev = pAdapter->dev;
10998 union iwreq_data wrqu;
10999 int we_event;
11000 char *msg;
11001
11002 memset(&wrqu, '\0', sizeof(wrqu));
11003 we_event = SIOCGIWSCAN;
11004 msg = NULL;
11005 wireless_send_event(dev, we_event, &wrqu, msg);
11006 }
11007 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070011008 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011009
11010 /* Get the Scan Req */
11011 req = pAdapter->request;
11012
11013 if (!req)
11014 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011015 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011016 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070011017 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070011018 }
11019
Jeff Johnson295189b2012-06-20 16:38:30 -070011020 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070011021 /* Scan is no longer pending */
11022 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011023
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011024 /* last_scan_timestamp is used to decide if new scan
11025 * is needed or not on station interface. If last station
11026 * scan time and new station scan time is less then
11027 * last_scan_timestamp ; driver will return cached scan.
11028 */
11029 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
11030 {
11031 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
11032
11033 if ( req->n_channels )
11034 {
11035 for (i = 0; i < req->n_channels ; i++ )
11036 {
11037 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
11038 }
11039 /* store no of channel scanned */
11040 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
11041 }
11042
11043 }
11044
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070011045 /*
11046 * cfg80211_scan_done informing NL80211 about completion
11047 * of scanning
11048 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053011049 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
11050 {
11051 aborted = true;
11052 }
11053 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080011054 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070011055
Siddharth Bhal76972212014-10-15 16:22:51 +053011056 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
11057 /* Generate new random mac addr for next scan */
11058 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
11059 hdd_processSpoofMacAddrRequest(pHddCtx);
11060 }
11061
Jeff Johnsone7245742012-09-05 17:12:55 -070011062allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011063 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011064 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011065
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070011066 /* Acquire wakelock to handle the case where APP's tries to suspend
11067 * immediatly after the driver gets connect request(i.e after scan)
11068 * from supplicant, this result in app's is suspending and not able
11069 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011070 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070011071
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070011072#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011073 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070011074#endif
11075
Jeff Johnson295189b2012-06-20 16:38:30 -070011076 EXIT();
11077 return 0;
11078}
11079
11080/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053011081 * FUNCTION: hdd_isConnectionInProgress
11082 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011083 *
11084 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011085v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011086{
11087 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
11088 hdd_station_ctx_t *pHddStaCtx = NULL;
11089 hdd_adapter_t *pAdapter = NULL;
11090 VOS_STATUS status = 0;
11091 v_U8_t staId = 0;
11092 v_U8_t *staMac = NULL;
11093
c_hpothu9b781ba2013-12-30 20:57:45 +053011094 if (TRUE == pHddCtx->btCoexModeSet)
11095 {
11096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053011097 FL("BTCoex Mode operation in progress"));
11098 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053011099 }
11100
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011101 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
11102
11103 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
11104 {
11105 pAdapter = pAdapterNode->pAdapter;
11106
11107 if( pAdapter )
11108 {
11109 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011110 "%s: Adapter with device mode %s (%d) exists",
11111 __func__, hdd_device_modetoString(pAdapter->device_mode),
11112 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011113 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053011114 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11115 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
11116 (eConnectionState_Connecting ==
11117 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
11118 {
11119 hddLog(VOS_TRACE_LEVEL_ERROR,
11120 "%s: %p(%d) Connection is in progress", __func__,
11121 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
11122 return VOS_TRUE;
11123 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011124 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053011125 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011126 {
11127 hddLog(VOS_TRACE_LEVEL_ERROR,
11128 "%s: %p(%d) Reassociation is in progress", __func__,
11129 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
11130 return VOS_TRUE;
11131 }
11132 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011133 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11134 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011135 {
11136 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11137 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011138 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011139 {
11140 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
11141 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080011142 "%s: client " MAC_ADDRESS_STR
11143 " is in the middle of WPS/EAPOL exchange.", __func__,
11144 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053011145 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011146 }
11147 }
11148 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
11149 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
11150 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011151 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
11152 ptSapContext pSapCtx = NULL;
11153 pSapCtx = VOS_GET_SAP_CB(pVosContext);
11154 if(pSapCtx == NULL){
11155 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
11156 FL("psapCtx is NULL"));
11157 return VOS_FALSE;
11158 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011159 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
11160 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011161 if ((pSapCtx->aStaInfo[staId].isUsed) &&
11162 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011163 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053011164 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011165
11166 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080011167 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
11168 "middle of WPS/EAPOL exchange.", __func__,
11169 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053011170 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011171 }
11172 }
11173 }
11174 }
11175 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
11176 pAdapterNode = pNext;
11177 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053011178 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011179}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011180
11181/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011182 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070011183 * this scan respond to scan trigger and update cfg80211 scan database
11184 * later, scan dump command can be used to recieve scan results
11185 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011186int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080011187#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11188 struct net_device *dev,
11189#endif
11190 struct cfg80211_scan_request *request)
11191{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011192 hdd_adapter_t *pAdapter = NULL;
11193 hdd_context_t *pHddCtx = NULL;
11194 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011195 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011196 tCsrScanRequest scanRequest;
11197 tANI_U8 *channelList = NULL, i;
11198 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011199 int status;
11200 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011201 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011202 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053011203 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011204 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053011205 v_S7_t rssi=0;
11206 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070011207
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011208#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
11209 struct net_device *dev = NULL;
11210 if (NULL == request)
11211 {
11212 hddLog(VOS_TRACE_LEVEL_ERROR,
11213 "%s: scan req param null", __func__);
11214 return -EINVAL;
11215 }
11216 dev = request->wdev->netdev;
11217#endif
11218
11219 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
11220 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
11221 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11222
Jeff Johnson295189b2012-06-20 16:38:30 -070011223 ENTER();
11224
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011225 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
11226 __func__, hdd_device_modetoString(pAdapter->device_mode),
11227 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053011228
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011229 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011230 if (0 != status)
11231 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011232 return status;
11233 }
11234
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011235 if (NULL == pwextBuf)
11236 {
11237 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
11238 __func__);
11239 return -EIO;
11240 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053011241 cfg_param = pHddCtx->cfg_ini;
11242 pScanInfo = &pHddCtx->scan_info;
11243
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053011244 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11245 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
11246 {
11247 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
11248 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
11249 }
11250
Jeff Johnson295189b2012-06-20 16:38:30 -070011251#ifdef WLAN_BTAMP_FEATURE
11252 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011253 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070011254 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011255 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011256 "%s: No scanning when AMP is on", __func__);
11257 return -EOPNOTSUPP;
11258 }
11259#endif
11260 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011261 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070011262 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011263 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011264 "%s: Not scanning on device_mode = %s (%d)",
11265 __func__, hdd_device_modetoString(pAdapter->device_mode),
11266 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070011267 return -EOPNOTSUPP;
11268 }
11269
11270 if (TRUE == pScanInfo->mScanPending)
11271 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053011272 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
11273 {
11274 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
11275 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011276 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070011277 }
11278
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053011279 // Don't allow scan if PNO scan is going on.
11280 if (pHddCtx->isPnoEnable)
11281 {
11282 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11283 FL("pno scan in progress"));
11284 return -EBUSY;
11285 }
11286
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011287 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070011288 //Channel and action frame is pending
11289 //Otherwise Cancel Remain On Channel and allow Scan
11290 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080011291 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070011292 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053011293 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070011294 return -EBUSY;
11295 }
11296
Jeff Johnson295189b2012-06-20 16:38:30 -070011297 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
11298 {
11299 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080011300 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011301 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011302 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011303 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
11304 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011305 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011306 "%s: MAX TM Level Scan not allowed", __func__);
11307 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011308 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070011309 }
11310 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
11311
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011312 /* Check if scan is allowed at this point of time.
11313 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053011314 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080011315 {
11316 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
11317 return -EBUSY;
11318 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011319
Jeff Johnson295189b2012-06-20 16:38:30 -070011320 vos_mem_zero( &scanRequest, sizeof(scanRequest));
11321
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011322 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
11323 * Becasue of this, driver is assuming that this is not wildcard scan and so
11324 * is not aging out the scan results.
11325 */
11326 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011327 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011328 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011329 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011330
11331 if ((request->ssids) && (0 < request->n_ssids))
11332 {
11333 tCsrSSIDInfo *SsidInfo;
11334 int j;
11335 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
11336 /* Allocate num_ssid tCsrSSIDInfo structure */
11337 SsidInfo = scanRequest.SSIDs.SSIDList =
11338 ( tCsrSSIDInfo *)vos_mem_malloc(
11339 request->n_ssids*sizeof(tCsrSSIDInfo));
11340
11341 if(NULL == scanRequest.SSIDs.SSIDList)
11342 {
11343 hddLog(VOS_TRACE_LEVEL_ERROR,
11344 "%s: memory alloc failed SSIDInfo buffer", __func__);
11345 return -ENOMEM;
11346 }
11347
11348 /* copy all the ssid's and their length */
11349 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
11350 {
11351 /* get the ssid length */
11352 SsidInfo->SSID.length = request->ssids[j].ssid_len;
11353 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
11354 SsidInfo->SSID.length);
11355 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
11356 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
11357 j, SsidInfo->SSID.ssId);
11358 }
11359 /* set the scan type to active */
11360 scanRequest.scanType = eSIR_ACTIVE_SCAN;
11361 }
11362 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011363 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011364 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11365 TRACE_CODE_HDD_CFG80211_SCAN,
11366 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070011367 /* set the scan type to active */
11368 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070011369 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011370 else
11371 {
11372 /*Set the scan type to default type, in this case it is ACTIVE*/
11373 scanRequest.scanType = pScanInfo->scan_mode;
11374 }
11375 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
11376 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070011377
11378 /* set BSSType to default type */
11379 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
11380
11381 /*TODO: scan the requested channels only*/
11382
11383 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011384 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070011385 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011386 hddLog(VOS_TRACE_LEVEL_WARN,
11387 "No of Scan Channels exceeded limit: %d", request->n_channels);
11388 request->n_channels = MAX_CHANNEL;
11389 }
11390
11391 hddLog(VOS_TRACE_LEVEL_INFO,
11392 "No of Scan Channels: %d", request->n_channels);
11393
11394
11395 if( request->n_channels )
11396 {
11397 char chList [(request->n_channels*5)+1];
11398 int len;
11399 channelList = vos_mem_malloc( request->n_channels );
11400 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053011401 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011402 hddLog(VOS_TRACE_LEVEL_ERROR,
11403 "%s: memory alloc failed channelList", __func__);
11404 status = -ENOMEM;
11405 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053011406 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011407
11408 for( i = 0, len = 0; i < request->n_channels ; i++ )
11409 {
11410 channelList[i] = request->channels[i]->hw_value;
11411 len += snprintf(chList+len, 5, "%d ", channelList[i]);
11412 }
11413
Nirav Shah20ac06f2013-12-12 18:14:06 +053011414 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011415 "Channel-List: %s ", chList);
11416 }
c_hpothu53512302014-04-15 18:49:53 +053011417
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011418 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
11419 scanRequest.ChannelInfo.ChannelList = channelList;
11420
11421 /* set requestType to full scan */
11422 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
11423
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011424 /* if there is back to back scan happening in driver with in
11425 * nDeferScanTimeInterval interval driver should defer new scan request
11426 * and should provide last cached scan results instead of new channel list.
11427 * This rule is not applicable if scan is p2p scan.
11428 * This condition will work only in case when last request no of channels
11429 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053011430 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053011431 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011432 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011433
Sushant Kaushik86592172015-04-27 16:35:03 +053011434 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
11435 /* if wps ie is NULL , then only defer scan */
11436 if ( pWpsIe == NULL &&
11437 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053011438 {
11439 if ( pScanInfo->last_scan_timestamp !=0 &&
11440 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
11441 {
11442 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
11443 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
11444 vos_mem_compare(pScanInfo->last_scan_channelList,
11445 channelList, pScanInfo->last_scan_numChannels))
11446 {
11447 hddLog(VOS_TRACE_LEVEL_WARN,
11448 " New and old station scan time differ is less then %u",
11449 pHddCtx->cfg_ini->nDeferScanTimeInterval);
11450
11451 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011452 pAdapter);
11453
Agarwal Ashish57e84372014-12-05 18:26:53 +053011454 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053011455 "Return old cached scan as all channels and no of channels are same");
11456
Agarwal Ashish57e84372014-12-05 18:26:53 +053011457 if (0 > ret)
11458 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011459
Agarwal Ashish57e84372014-12-05 18:26:53 +053011460 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053011461
11462 status = eHAL_STATUS_SUCCESS;
11463 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053011464 }
11465 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011466 }
11467
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011468 /* Flush the scan results(only p2p beacons) for STA scan and P2P
11469 * search (Flush on both full scan and social scan but not on single
11470 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
11471 */
11472
11473 /* Supplicant does single channel scan after 8-way handshake
11474 * and in that case driver shoudnt flush scan results. If
11475 * driver flushes the scan results here and unfortunately if
11476 * the AP doesnt respond to our probe req then association
11477 * fails which is not desired
11478 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011479 if ((request->n_ssids == 1)
11480 && (request->ssids != NULL)
11481 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
11482 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011483
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011484 if( is_p2p_scan ||
11485 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011486 {
11487 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
11488 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
11489 pAdapter->sessionId );
11490 }
11491
11492 if( request->ie_len )
11493 {
11494 /* save this for future association (join requires this) */
11495 /*TODO: Array needs to be converted to dynamic allocation,
11496 * as multiple ie.s can be sent in cfg80211_scan_request structure
11497 * CR 597966
11498 */
11499 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
11500 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
11501 pScanInfo->scanAddIE.length = request->ie_len;
11502
11503 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11504 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11505 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011506 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011507 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070011508 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011509 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
11510 memcpy( pwextBuf->roamProfile.addIEScan,
11511 request->ie, request->ie_len);
11512 }
11513 else
11514 {
11515 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
11516 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011517 }
11518
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011519 }
11520 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
11521 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
11522
11523 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
11524 request->ie_len);
11525 if (pP2pIe != NULL)
11526 {
11527#ifdef WLAN_FEATURE_P2P_DEBUG
11528 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
11529 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
11530 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053011531 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011532 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
11533 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11534 "Go nego completed to Connection is started");
11535 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11536 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053011537 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011538 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
11539 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011540 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011541 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
11542 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11543 "Disconnected state to Connection is started");
11544 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11545 "for 4way Handshake");
11546 }
11547#endif
11548
11549 /* no_cck will be set during p2p find to disable 11b rates */
11550 if(TRUE == request->no_cck)
11551 {
11552 hddLog(VOS_TRACE_LEVEL_INFO,
11553 "%s: This is a P2P Search", __func__);
11554 scanRequest.p2pSearch = 1;
11555
11556 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053011557 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011558 /* set requestType to P2P Discovery */
11559 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
11560 }
11561
11562 /*
11563 Skip Dfs Channel in case of P2P Search
11564 if it is set in ini file
11565 */
11566 if(cfg_param->skipDfsChnlInP2pSearch)
11567 {
11568 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011569 }
11570 else
11571 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011572 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011573 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011574
Agarwal Ashish4f616132013-12-30 23:32:50 +053011575 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011576 }
11577 }
11578
11579 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
11580
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011581#ifdef FEATURE_WLAN_TDLS
11582 /* if tdls disagree scan right now, return immediately.
11583 tdls will schedule the scan when scan is allowed. (return SUCCESS)
11584 or will reject the scan if any TDLS is in progress. (return -EBUSY)
11585 */
11586 status = wlan_hdd_tdls_scan_callback (pAdapter,
11587 wiphy,
11588#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11589 dev,
11590#endif
11591 request);
11592 if(status <= 0)
11593 {
11594 if(!status)
11595 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
11596 "scan rejected %d", __func__, status);
11597 else
11598 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
11599 __func__, status);
11600
11601 return status;
11602 }
11603#endif
11604
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011605 /* acquire the wakelock to avoid the apps suspend during the scan. To
11606 * address the following issues.
11607 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
11608 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
11609 * for long time, this result in apps running at full power for long time.
11610 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
11611 * be stuck in full power because of resume BMPS
11612 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011613 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011614
Nirav Shah20ac06f2013-12-12 18:14:06 +053011615 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11616 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011617 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
11618 scanRequest.requestType, scanRequest.scanType,
11619 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053011620 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
11621
Siddharth Bhal76972212014-10-15 16:22:51 +053011622 if (pHddCtx->spoofMacAddr.isEnabled)
11623 {
11624 hddLog(VOS_TRACE_LEVEL_INFO,
11625 "%s: MAC Spoofing enabled for current scan", __func__);
11626 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
11627 * to fill TxBds for probe request during current scan
11628 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011629 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053011630 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011631
11632 if(status != VOS_STATUS_SUCCESS)
11633 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011634 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011635 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053011636#ifdef FEATURE_WLAN_TDLS
11637 wlan_hdd_tdls_scan_done_callback(pAdapter);
11638#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011639 goto free_mem;
11640 }
Siddharth Bhal76972212014-10-15 16:22:51 +053011641 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053011642 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070011643 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011644 pAdapter->sessionId, &scanRequest, &scanId,
11645 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070011646
Jeff Johnson295189b2012-06-20 16:38:30 -070011647 if (eHAL_STATUS_SUCCESS != status)
11648 {
11649 hddLog(VOS_TRACE_LEVEL_ERROR,
11650 "%s: sme_ScanRequest returned error %d", __func__, status);
11651 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011652 if(eHAL_STATUS_RESOURCES == status)
11653 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011654 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
11655 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011656 status = -EBUSY;
11657 } else {
11658 status = -EIO;
11659 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011660 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011661
11662#ifdef FEATURE_WLAN_TDLS
11663 wlan_hdd_tdls_scan_done_callback(pAdapter);
11664#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011665 goto free_mem;
11666 }
11667
11668 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011669 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011670 pAdapter->request = request;
11671 pScanInfo->scanId = scanId;
11672
11673 complete(&pScanInfo->scan_req_completion_event);
11674
11675free_mem:
11676 if( scanRequest.SSIDs.SSIDList )
11677 {
11678 vos_mem_free(scanRequest.SSIDs.SSIDList);
11679 }
11680
11681 if( channelList )
11682 vos_mem_free( channelList );
11683
11684 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011685 return status;
11686}
11687
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011688int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
11689#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11690 struct net_device *dev,
11691#endif
11692 struct cfg80211_scan_request *request)
11693{
11694 int ret;
11695
11696 vos_ssr_protect(__func__);
11697 ret = __wlan_hdd_cfg80211_scan(wiphy,
11698#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11699 dev,
11700#endif
11701 request);
11702 vos_ssr_unprotect(__func__);
11703
11704 return ret;
11705}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011706
11707void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
11708{
11709 v_U8_t iniDot11Mode =
11710 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
11711 eHddDot11Mode hddDot11Mode = iniDot11Mode;
11712
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011713 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
11714 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011715 switch ( iniDot11Mode )
11716 {
11717 case eHDD_DOT11_MODE_AUTO:
11718 case eHDD_DOT11_MODE_11ac:
11719 case eHDD_DOT11_MODE_11ac_ONLY:
11720#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053011721 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
11722 sme_IsFeatureSupportedByFW(DOT11AC) )
11723 hddDot11Mode = eHDD_DOT11_MODE_11ac;
11724 else
11725 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011726#else
11727 hddDot11Mode = eHDD_DOT11_MODE_11n;
11728#endif
11729 break;
11730 case eHDD_DOT11_MODE_11n:
11731 case eHDD_DOT11_MODE_11n_ONLY:
11732 hddDot11Mode = eHDD_DOT11_MODE_11n;
11733 break;
11734 default:
11735 hddDot11Mode = iniDot11Mode;
11736 break;
11737 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011738#ifdef WLAN_FEATURE_AP_HT40_24G
11739 if (operationChannel > SIR_11B_CHANNEL_END)
11740#endif
11741 {
11742 /* This call decides required channel bonding mode */
11743 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011744 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
11745 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011746 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011747}
11748
Jeff Johnson295189b2012-06-20 16:38:30 -070011749/*
11750 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011751 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011752 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011753int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011754 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070011755{
11756 int status = 0;
11757 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080011758 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011759 v_U32_t roamId;
11760 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070011761 eCsrAuthType RSNAuthType;
11762
11763 ENTER();
11764
11765 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080011766 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11767
11768 status = wlan_hdd_validate_context(pHddCtx);
11769 if (status)
11770 {
Yue Mae36e3552014-03-05 17:06:20 -080011771 return status;
11772 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011773
Jeff Johnson295189b2012-06-20 16:38:30 -070011774 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
11775 {
11776 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
11777 return -EINVAL;
11778 }
11779
11780 pRoamProfile = &pWextState->roamProfile;
11781
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011782 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070011783 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011784 hdd_station_ctx_t *pHddStaCtx;
11785 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011786
Siddharth Bhalda0d1622015-04-24 15:47:49 +053011787 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
11788
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011789 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070011790 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
11791 {
11792 /*QoS not enabled in cfg file*/
11793 pRoamProfile->uapsd_mask = 0;
11794 }
11795 else
11796 {
11797 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011798 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070011799 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
11800 }
11801
11802 pRoamProfile->SSIDs.numOfSSIDs = 1;
11803 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
11804 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011805 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070011806 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
11807 ssid, ssid_len);
11808
11809 if (bssid)
11810 {
11811 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
11812 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
11813 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011814 /* Save BSSID in seperate variable as well, as RoamProfile
11815 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070011816 case of join failure we should send valid BSSID to supplicant
11817 */
11818 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
11819 WNI_CFG_BSSID_LEN);
11820 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070011821 else
11822 {
11823 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
11824 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011825
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011826 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
11827 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011828 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
11829 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011830 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011831 /*set gen ie*/
11832 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
11833 /*set auth*/
11834 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
11835 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011836#ifdef FEATURE_WLAN_WAPI
11837 if (pAdapter->wapi_info.nWapiMode)
11838 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011839 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011840 switch (pAdapter->wapi_info.wapiAuthMode)
11841 {
11842 case WAPI_AUTH_MODE_PSK:
11843 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011844 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011845 pAdapter->wapi_info.wapiAuthMode);
11846 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
11847 break;
11848 }
11849 case WAPI_AUTH_MODE_CERT:
11850 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011851 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011852 pAdapter->wapi_info.wapiAuthMode);
11853 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
11854 break;
11855 }
11856 } // End of switch
11857 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
11858 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
11859 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011860 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011861 pRoamProfile->AuthType.numEntries = 1;
11862 pRoamProfile->EncryptionType.numEntries = 1;
11863 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11864 pRoamProfile->mcEncryptionType.numEntries = 1;
11865 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11866 }
11867 }
11868#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011869#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011870 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011871 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11872 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
11873 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011874 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
11875 sizeof (tSirGtkOffloadParams));
11876 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011877 }
11878#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011879 pRoamProfile->csrPersona = pAdapter->device_mode;
11880
Jeff Johnson32d95a32012-09-10 13:15:23 -070011881 if( operatingChannel )
11882 {
11883 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
11884 pRoamProfile->ChannelInfo.numOfChannels = 1;
11885 }
Chet Lanctot186b5732013-03-18 10:26:30 -070011886 else
11887 {
11888 pRoamProfile->ChannelInfo.ChannelList = NULL;
11889 pRoamProfile->ChannelInfo.numOfChannels = 0;
11890 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011891 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
11892 {
11893 hdd_select_cbmode(pAdapter,operatingChannel);
11894 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011895
Agarwal Ashish40f9b872015-09-01 16:17:35 +053011896 /*
11897 * Change conn_state to connecting before sme_RoamConnect(),
11898 * because sme_RoamConnect() has a direct path to call
11899 * hdd_smeRoamCallback(), which will change the conn_state
11900 * If direct path, conn_state will be accordingly changed
11901 * to NotConnected or Associated by either
11902 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
11903 * in sme_RoamCallback()
11904 * if sme_RomConnect is to be queued,
11905 * Connecting state will remain until it is completed.
11906 * If connection state is not changed,
11907 * connection state will remain in eConnectionState_NotConnected state.
11908 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
11909 * if conn state is eConnectionState_NotConnected.
11910 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
11911 * informed of connect result indication which is an issue.
11912 */
11913
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011914 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11915 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053011916 {
11917 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053011918 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011919 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
11920 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053011921 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011922 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011923 pAdapter->sessionId, pRoamProfile, &roamId);
11924
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011925 if ((eHAL_STATUS_SUCCESS != status) &&
11926 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11927 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011928
11929 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053011930 hddLog(VOS_TRACE_LEVEL_ERROR,
11931 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
11932 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011933 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011934 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011935 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011936 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011937
11938 pRoamProfile->ChannelInfo.ChannelList = NULL;
11939 pRoamProfile->ChannelInfo.numOfChannels = 0;
11940
Jeff Johnson295189b2012-06-20 16:38:30 -070011941 }
11942 else
11943 {
11944 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
11945 return -EINVAL;
11946 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011947 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011948 return status;
11949}
11950
11951/*
11952 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
11953 * This function is used to set the authentication type (OPEN/SHARED).
11954 *
11955 */
11956static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
11957 enum nl80211_auth_type auth_type)
11958{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011959 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011960 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11961
11962 ENTER();
11963
11964 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011965 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070011966 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011967 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011968 hddLog(VOS_TRACE_LEVEL_INFO,
11969 "%s: set authentication type to AUTOSWITCH", __func__);
11970 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
11971 break;
11972
11973 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011974#ifdef WLAN_FEATURE_VOWIFI_11R
11975 case NL80211_AUTHTYPE_FT:
11976#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011977 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011978 "%s: set authentication type to OPEN", __func__);
11979 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
11980 break;
11981
11982 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011983 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011984 "%s: set authentication type to SHARED", __func__);
11985 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
11986 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011987#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011988 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011989 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011990 "%s: set authentication type to CCKM WPA", __func__);
11991 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
11992 break;
11993#endif
11994
11995
11996 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011997 hddLog(VOS_TRACE_LEVEL_ERROR,
11998 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011999 auth_type);
12000 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
12001 return -EINVAL;
12002 }
12003
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012004 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012005 pHddStaCtx->conn_info.authType;
12006 return 0;
12007}
12008
12009/*
12010 * FUNCTION: wlan_hdd_set_akm_suite
12011 * This function is used to set the key mgmt type(PSK/8021x).
12012 *
12013 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012014static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012015 u32 key_mgmt
12016 )
12017{
12018 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12019 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053012020 /* Should be in ieee802_11_defs.h */
12021#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
12022#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070012023 /*set key mgmt type*/
12024 switch(key_mgmt)
12025 {
12026 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053012027 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012028#ifdef WLAN_FEATURE_VOWIFI_11R
12029 case WLAN_AKM_SUITE_FT_PSK:
12030#endif
12031 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070012032 __func__);
12033 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
12034 break;
12035
12036 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053012037 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053012038#ifdef WLAN_FEATURE_VOWIFI_11R
12039 case WLAN_AKM_SUITE_FT_8021X:
12040#endif
12041 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070012042 __func__);
12043 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
12044 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012045#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012046#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
12047#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
12048 case WLAN_AKM_SUITE_CCKM:
12049 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
12050 __func__);
12051 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
12052 break;
12053#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070012054#ifndef WLAN_AKM_SUITE_OSEN
12055#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
12056 case WLAN_AKM_SUITE_OSEN:
12057 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
12058 __func__);
12059 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
12060 break;
12061#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012062
12063 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012064 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012065 __func__, key_mgmt);
12066 return -EINVAL;
12067
12068 }
12069 return 0;
12070}
12071
12072/*
12073 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012074 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070012075 * (NONE/WEP40/WEP104/TKIP/CCMP).
12076 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012077static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
12078 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070012079 bool ucast
12080 )
12081{
12082 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012083 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012084 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12085
12086 ENTER();
12087
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012088 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012089 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053012090 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070012091 __func__, cipher);
12092 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12093 }
12094 else
12095 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012096
Jeff Johnson295189b2012-06-20 16:38:30 -070012097 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012098 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070012099 {
12100 case IW_AUTH_CIPHER_NONE:
12101 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12102 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012103
Jeff Johnson295189b2012-06-20 16:38:30 -070012104 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012105 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070012106 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012107
Jeff Johnson295189b2012-06-20 16:38:30 -070012108 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053012109 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070012110 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012111
Jeff Johnson295189b2012-06-20 16:38:30 -070012112 case WLAN_CIPHER_SUITE_TKIP:
12113 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
12114 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012115
Jeff Johnson295189b2012-06-20 16:38:30 -070012116 case WLAN_CIPHER_SUITE_CCMP:
12117 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12118 break;
12119#ifdef FEATURE_WLAN_WAPI
12120 case WLAN_CIPHER_SUITE_SMS4:
12121 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
12122 break;
12123#endif
12124
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080012125#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070012126 case WLAN_CIPHER_SUITE_KRK:
12127 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
12128 break;
12129#endif
12130 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012131 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012132 __func__, cipher);
12133 return -EOPNOTSUPP;
12134 }
12135 }
12136
12137 if (ucast)
12138 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012139 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012140 __func__, encryptionType);
12141 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12142 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012143 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012144 encryptionType;
12145 }
12146 else
12147 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012148 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012149 __func__, encryptionType);
12150 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
12151 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
12152 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
12153 }
12154
12155 return 0;
12156}
12157
12158
12159/*
12160 * FUNCTION: wlan_hdd_cfg80211_set_ie
12161 * This function is used to parse WPA/RSN IE's.
12162 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012163int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012164#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12165 const u8 *ie,
12166#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012167 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012168#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012169 size_t ie_len
12170 )
12171{
12172 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012173#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
12174 const u8 *genie = ie;
12175#else
Jeff Johnson295189b2012-06-20 16:38:30 -070012176 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012177#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012178 v_U16_t remLen = ie_len;
12179#ifdef FEATURE_WLAN_WAPI
12180 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
12181 u16 *tmp;
12182 v_U16_t akmsuiteCount;
12183 int *akmlist;
12184#endif
12185 ENTER();
12186
12187 /* clear previous assocAddIE */
12188 pWextState->assocAddIE.length = 0;
12189 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012190 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012191
12192 while (remLen >= 2)
12193 {
12194 v_U16_t eLen = 0;
12195 v_U8_t elementId;
12196 elementId = *genie++;
12197 eLen = *genie++;
12198 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012199
Arif Hussain6d2a3322013-11-17 19:50:10 -080012200 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070012201 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012202
12203 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070012204 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012205 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012206 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 -070012207 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012208 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012209 "%s: Invalid WPA IE", __func__);
12210 return -EINVAL;
12211 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012212 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070012213 {
12214 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012215 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012216 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012217
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012218 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012219 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012220 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
12221 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012222 VOS_ASSERT(0);
12223 return -ENOMEM;
12224 }
12225 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
12226 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12227 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012228
Jeff Johnson295189b2012-06-20 16:38:30 -070012229 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
12230 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12231 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12232 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012233 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
12234 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012235 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
12236 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
12237 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
12238 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
12239 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
12240 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012241 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053012242 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070012243 {
12244 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012245 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012246 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012247
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012248 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012249 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012250 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12251 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012252 VOS_ASSERT(0);
12253 return -ENOMEM;
12254 }
12255 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
12256 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12257 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012258
Jeff Johnson295189b2012-06-20 16:38:30 -070012259 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12260 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12261 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012262#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012263 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
12264 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070012265 /*Consider WFD IE, only for P2P Client */
12266 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
12267 {
12268 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012269 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070012270 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012271
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012272 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070012273 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012274 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12275 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070012276 VOS_ASSERT(0);
12277 return -ENOMEM;
12278 }
12279 // WFD IE is saved to Additional IE ; it should be accumulated to handle
12280 // WPS IE + P2P IE + WFD IE
12281 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12282 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012283
Jeff Johnson295189b2012-06-20 16:38:30 -070012284 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12285 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12286 }
12287#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012288 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012289 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012290 HS20_OUI_TYPE_SIZE)) )
12291 {
12292 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012293 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012294 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012295
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012296 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012297 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012298 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12299 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012300 VOS_ASSERT(0);
12301 return -ENOMEM;
12302 }
12303 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12304 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012305
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070012306 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12307 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12308 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012309 /* Appending OSEN Information Element in Assiciation Request */
12310 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
12311 OSEN_OUI_TYPE_SIZE)) )
12312 {
12313 v_U16_t curAddIELen = pWextState->assocAddIE.length;
12314 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
12315 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012316
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012317 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012318 {
12319 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12320 "Need bigger buffer space");
12321 VOS_ASSERT(0);
12322 return -ENOMEM;
12323 }
12324 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12325 pWextState->assocAddIE.length += eLen + 2;
12326
12327 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
12328 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12329 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12330 }
12331
Abhishek Singh4322e622015-06-10 15:42:54 +053012332 /* Update only for WPA IE */
12333 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
12334 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070012335
12336 /* populating as ADDIE in beacon frames */
12337 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012338 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070012339 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
12340 {
12341 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
12342 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
12343 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
12344 {
12345 hddLog(LOGE,
12346 "Coldn't pass "
12347 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
12348 }
12349 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
12350 else
12351 hddLog(LOGE,
12352 "Could not pass on "
12353 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
12354
12355 /* IBSS mode doesn't contain params->proberesp_ies still
12356 beaconIE's need to be populated in probe response frames */
12357 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
12358 {
12359 u16 rem_probe_resp_ie_len = eLen + 2;
12360 u8 probe_rsp_ie_len[3] = {0};
12361 u8 counter = 0;
12362
12363 /* Check Probe Resp Length if it is greater then 255 then
12364 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
12365 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
12366 not able Store More then 255 bytes into One Variable */
12367
12368 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
12369 {
12370 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
12371 {
12372 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
12373 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
12374 }
12375 else
12376 {
12377 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
12378 rem_probe_resp_ie_len = 0;
12379 }
12380 }
12381
12382 rem_probe_resp_ie_len = 0;
12383
12384 if (probe_rsp_ie_len[0] > 0)
12385 {
12386 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12387 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
12388 (tANI_U8*)(genie - 2),
12389 probe_rsp_ie_len[0], NULL,
12390 eANI_BOOLEAN_FALSE)
12391 == eHAL_STATUS_FAILURE)
12392 {
12393 hddLog(LOGE,
12394 "Could not pass"
12395 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
12396 }
12397 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
12398 }
12399
12400 if (probe_rsp_ie_len[1] > 0)
12401 {
12402 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12403 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
12404 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
12405 probe_rsp_ie_len[1], NULL,
12406 eANI_BOOLEAN_FALSE)
12407 == eHAL_STATUS_FAILURE)
12408 {
12409 hddLog(LOGE,
12410 "Could not pass"
12411 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
12412 }
12413 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
12414 }
12415
12416 if (probe_rsp_ie_len[2] > 0)
12417 {
12418 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12419 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
12420 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
12421 probe_rsp_ie_len[2], NULL,
12422 eANI_BOOLEAN_FALSE)
12423 == eHAL_STATUS_FAILURE)
12424 {
12425 hddLog(LOGE,
12426 "Could not pass"
12427 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
12428 }
12429 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
12430 }
12431
12432 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
12433 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
12434 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
12435 {
12436 hddLog(LOGE,
12437 "Could not pass"
12438 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
12439 }
12440 }
12441 else
12442 {
12443 // Reset WNI_CFG_PROBE_RSP Flags
12444 wlan_hdd_reset_prob_rspies(pAdapter);
12445
12446 hddLog(VOS_TRACE_LEVEL_INFO,
12447 "%s: No Probe Response IE received in set beacon",
12448 __func__);
12449 }
12450 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012451 break;
12452 case DOT11F_EID_RSN:
12453 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
12454 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
12455 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
12456 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
12457 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
12458 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053012459
12460 /* Appending Extended Capabilities with Interworking bit set
12461 * in Assoc Req.
12462 *
12463 * In assoc req this EXT Cap will only be taken into account if
12464 * interworkingService bit is set to 1. Currently
12465 * driver is only interested in interworkingService capability
12466 * from supplicant. If in future any other EXT Cap info is
12467 * required from supplicat, it needs to be handled while
12468 * sending Assoc Req in LIM.
12469 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012470 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012471 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012472 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012473 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012474 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012475
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012476 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012477 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012478 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12479 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012480 VOS_ASSERT(0);
12481 return -ENOMEM;
12482 }
12483 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12484 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012485
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012486 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12487 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12488 break;
12489 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012490#ifdef FEATURE_WLAN_WAPI
12491 case WLAN_EID_WAPI:
12492 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012493 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012494 pAdapter->wapi_info.nWapiMode);
12495 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012496 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070012497 akmsuiteCount = WPA_GET_LE16(tmp);
12498 tmp = tmp + 1;
12499 akmlist = (int *)(tmp);
12500 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
12501 {
12502 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
12503 }
12504 else
12505 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012506 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070012507 VOS_ASSERT(0);
12508 return -EINVAL;
12509 }
12510
12511 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
12512 {
12513 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012514 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012515 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012516 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012517 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012518 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012519 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012520 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012521 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
12522 }
12523 break;
12524#endif
12525 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012526 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012527 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012528 /* when Unknown IE is received we should break and continue
12529 * to the next IE in the buffer instead we were returning
12530 * so changing this to break */
12531 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070012532 }
12533 genie += eLen;
12534 remLen -= eLen;
12535 }
12536 EXIT();
12537 return 0;
12538}
12539
12540/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012541 * FUNCTION: hdd_isWPAIEPresent
12542 * Parse the received IE to find the WPA IE
12543 *
12544 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012545static bool hdd_isWPAIEPresent(
12546#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
12547 const u8 *ie,
12548#else
12549 u8 *ie,
12550#endif
12551 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012552{
12553 v_U8_t eLen = 0;
12554 v_U16_t remLen = ie_len;
12555 v_U8_t elementId = 0;
12556
12557 while (remLen >= 2)
12558 {
12559 elementId = *ie++;
12560 eLen = *ie++;
12561 remLen -= 2;
12562 if (eLen > remLen)
12563 {
12564 hddLog(VOS_TRACE_LEVEL_ERROR,
12565 "%s: IE length is wrong %d", __func__, eLen);
12566 return FALSE;
12567 }
12568 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
12569 {
12570 /* OUI - 0x00 0X50 0XF2
12571 WPA Information Element - 0x01
12572 WPA version - 0x01*/
12573 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
12574 return TRUE;
12575 }
12576 ie += eLen;
12577 remLen -= eLen;
12578 }
12579 return FALSE;
12580}
12581
12582/*
Jeff Johnson295189b2012-06-20 16:38:30 -070012583 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012584 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012585 * parameters during connect operation.
12586 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012587int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012588 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012589 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012590{
12591 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012592 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012593 ENTER();
12594
12595 /*set wpa version*/
12596 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
12597
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012598 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012599 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053012600 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012601 {
12602 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12603 }
12604 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
12605 {
12606 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12607 }
12608 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012609
12610 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012611 pWextState->wpaVersion);
12612
12613 /*set authentication type*/
12614 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
12615
12616 if (0 > status)
12617 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012618 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012619 "%s: failed to set authentication type ", __func__);
12620 return status;
12621 }
12622
12623 /*set key mgmt type*/
12624 if (req->crypto.n_akm_suites)
12625 {
12626 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
12627 if (0 > status)
12628 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012629 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070012630 __func__);
12631 return status;
12632 }
12633 }
12634
12635 /*set pairwise cipher type*/
12636 if (req->crypto.n_ciphers_pairwise)
12637 {
12638 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
12639 req->crypto.ciphers_pairwise[0], true);
12640 if (0 > status)
12641 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012642 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012643 "%s: failed to set unicast cipher type", __func__);
12644 return status;
12645 }
12646 }
12647 else
12648 {
12649 /*Reset previous cipher suite to none*/
12650 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
12651 if (0 > status)
12652 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012653 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012654 "%s: failed to set unicast cipher type", __func__);
12655 return status;
12656 }
12657 }
12658
12659 /*set group cipher type*/
12660 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
12661 false);
12662
12663 if (0 > status)
12664 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012665 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070012666 __func__);
12667 return status;
12668 }
12669
Chet Lanctot186b5732013-03-18 10:26:30 -070012670#ifdef WLAN_FEATURE_11W
12671 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
12672#endif
12673
Jeff Johnson295189b2012-06-20 16:38:30 -070012674 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
12675 if (req->ie_len)
12676 {
12677 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
12678 if ( 0 > status)
12679 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012680 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012681 __func__);
12682 return status;
12683 }
12684 }
12685
12686 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012687 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012688 {
12689 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
12690 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
12691 )
12692 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012693 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070012694 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
12695 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012696 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012697 __func__);
12698 return -EOPNOTSUPP;
12699 }
12700 else
12701 {
12702 u8 key_len = req->key_len;
12703 u8 key_idx = req->key_idx;
12704
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012705 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012706 && (CSR_MAX_NUM_KEY > key_idx)
12707 )
12708 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012709 hddLog(VOS_TRACE_LEVEL_INFO,
12710 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012711 __func__, key_idx, key_len);
12712 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012713 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012714 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012715 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012716 (u8)key_len;
12717 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
12718 }
12719 }
12720 }
12721 }
12722
12723 return status;
12724}
12725
12726/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012727 * FUNCTION: wlan_hdd_try_disconnect
12728 * This function is used to disconnect from previous
12729 * connection
12730 */
12731static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
12732{
12733 long ret = 0;
12734 hdd_station_ctx_t *pHddStaCtx;
12735 eMib_dot11DesiredBssType connectedBssType;
12736
12737 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12738
12739 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
12740
12741 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
12742 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
12743 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
12744 {
12745 /* Issue disconnect to CSR */
12746 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12747 if( eHAL_STATUS_SUCCESS ==
12748 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12749 pAdapter->sessionId,
12750 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12751 {
12752 ret = wait_for_completion_interruptible_timeout(
12753 &pAdapter->disconnect_comp_var,
12754 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12755 if (0 >= ret)
12756 {
12757 hddLog(LOGE, FL("Failed to receive disconnect event"));
12758 return -EALREADY;
12759 }
12760 }
12761 }
12762 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
12763 {
12764 ret = wait_for_completion_interruptible_timeout(
12765 &pAdapter->disconnect_comp_var,
12766 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12767 if (0 >= ret)
12768 {
12769 hddLog(LOGE, FL("Failed to receive disconnect event"));
12770 return -EALREADY;
12771 }
12772 }
12773
12774 return 0;
12775}
12776
12777/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053012778 * FUNCTION: __wlan_hdd_cfg80211_connect
12779 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070012780 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012781static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012782 struct net_device *ndev,
12783 struct cfg80211_connect_params *req
12784 )
12785{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012786 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012787 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012788 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053012789 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012790
12791 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012792
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012793 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12794 TRACE_CODE_HDD_CFG80211_CONNECT,
12795 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012796 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012797 "%s: device_mode = %s (%d)", __func__,
12798 hdd_device_modetoString(pAdapter->device_mode),
12799 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012800
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012801 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012802 if (!pHddCtx)
12803 {
12804 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12805 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053012806 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012807 }
12808
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012809 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012810 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012811 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012812 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012813 }
12814
Agarwal Ashish51325b52014-06-16 16:50:49 +053012815 if (vos_max_concurrent_connections_reached()) {
12816 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12817 return -ECONNREFUSED;
12818 }
12819
Jeff Johnson295189b2012-06-20 16:38:30 -070012820#ifdef WLAN_BTAMP_FEATURE
12821 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012822 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070012823 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012824 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012825 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012826 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070012827 }
12828#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012829
12830 //If Device Mode is Station Concurrent Sessions Exit BMps
12831 //P2P Mode will be taken care in Open/close adapter
12832 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012833 (vos_concurrent_open_sessions_running())) {
12834 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
12835 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012836 }
12837
12838 /*Try disconnecting if already in connected state*/
12839 status = wlan_hdd_try_disconnect(pAdapter);
12840 if ( 0 > status)
12841 {
12842 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12843 " connection"));
12844 return -EALREADY;
12845 }
12846
Jeff Johnson295189b2012-06-20 16:38:30 -070012847 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012848 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070012849
12850 if ( 0 > status)
12851 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012852 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070012853 __func__);
12854 return status;
12855 }
Mohit Khanna765234a2012-09-11 15:08:35 -070012856 if ( req->channel )
12857 {
12858 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
12859 req->ssid_len, req->bssid,
12860 req->channel->hw_value);
12861 }
12862 else
12863 {
12864 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012865 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070012866 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012867
Sushant Kaushikd7083982015-03-18 14:33:24 +053012868 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012869 {
12870 //ReEnable BMPS if disabled
12871 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
12872 (NULL != pHddCtx))
12873 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012874 if (pHddCtx->hdd_wlan_suspended)
12875 {
12876 hdd_set_pwrparams(pHddCtx);
12877 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012878 //ReEnable Bmps and Imps back
12879 hdd_enable_bmps_imps(pHddCtx);
12880 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053012881 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070012882 return status;
12883 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012884 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012885 EXIT();
12886 return status;
12887}
12888
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012889static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
12890 struct net_device *ndev,
12891 struct cfg80211_connect_params *req)
12892{
12893 int ret;
12894 vos_ssr_protect(__func__);
12895 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
12896 vos_ssr_unprotect(__func__);
12897
12898 return ret;
12899}
Jeff Johnson295189b2012-06-20 16:38:30 -070012900
12901/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012902 * FUNCTION: wlan_hdd_disconnect
12903 * This function is used to issue a disconnect request to SME
12904 */
12905int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
12906{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012907 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012908 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012909 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012910 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012911
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012912 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012913
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012914 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012915 if (0 != status)
12916 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012917 return status;
12918 }
12919
Sushant Kaushikb4834d22015-07-15 15:29:05 +053012920 if (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)
12921 {
12922 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
12923 pAdapter->sessionId);
12924 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012925 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012926
Agarwal Ashish47d18112014-08-04 19:55:07 +053012927 /* Need to apply spin lock before decreasing active sessions
12928 * as there can be chance for double decrement if context switch
12929 * Calls hdd_DisConnectHandler.
12930 */
12931
12932 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012933 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
12934 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012935 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
12936 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053012937 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
12938 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012939
Abhishek Singhf4669da2014-05-26 15:07:49 +053012940 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053012941 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
12942
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012943 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012944
Mihir Shete182a0b22014-08-18 16:08:48 +053012945 /*
12946 * stop tx queues before deleting STA/BSS context from the firmware.
12947 * tx has to be disabled because the firmware can get busy dropping
12948 * the tx frames after BSS/STA has been deleted and will not send
12949 * back a response resulting in WDI timeout
12950 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053012951 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053012952 netif_tx_disable(pAdapter->dev);
12953 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012954
Mihir Shete182a0b22014-08-18 16:08:48 +053012955 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012956 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12957 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012958 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
12959 {
12960 hddLog(VOS_TRACE_LEVEL_INFO,
12961 FL("status = %d, already disconnected"),
12962 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012963
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012964 }
12965 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012966 {
12967 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012968 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012969 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012970 result = -EINVAL;
12971 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012972 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012973 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012974 &pAdapter->disconnect_comp_var,
12975 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012976 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012977 {
12978 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012979 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012980 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012981 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012982 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012983 {
12984 hddLog(VOS_TRACE_LEVEL_ERROR,
12985 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012986 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012987 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012988disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012989 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12990 FL("Set HDD connState to eConnectionState_NotConnected"));
12991 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
12992
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012993 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012994 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012995}
12996
12997
12998/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012999 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070013000 * This function is used to issue a disconnect request to SME
13001 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013002static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013003 struct net_device *dev,
13004 u16 reason
13005 )
13006{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013007 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013008 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013009 tCsrRoamProfile *pRoamProfile;
13010 hdd_station_ctx_t *pHddStaCtx;
13011 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013012#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013013 tANI_U8 staIdx;
13014#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013015
Jeff Johnson295189b2012-06-20 16:38:30 -070013016 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013017
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053013018 if (!pAdapter) {
13019 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
13020 return -EINVAL;
13021 }
13022
13023 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13024 if (!pHddStaCtx) {
13025 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
13026 return -EINVAL;
13027 }
13028
13029 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13030 status = wlan_hdd_validate_context(pHddCtx);
13031 if (0 != status)
13032 {
13033 return status;
13034 }
13035
13036 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
13037
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013038 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13039 TRACE_CODE_HDD_CFG80211_DISCONNECT,
13040 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013041 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
13042 __func__, hdd_device_modetoString(pAdapter->device_mode),
13043 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013044
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013045 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
13046 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070013047
Jeff Johnson295189b2012-06-20 16:38:30 -070013048 if (NULL != pRoamProfile)
13049 {
13050 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053013051 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
13052 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070013053 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013054 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070013055 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013056 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070013057 switch(reason)
13058 {
13059 case WLAN_REASON_MIC_FAILURE:
13060 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
13061 break;
13062
13063 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
13064 case WLAN_REASON_DISASSOC_AP_BUSY:
13065 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
13066 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
13067 break;
13068
13069 case WLAN_REASON_PREV_AUTH_NOT_VALID:
13070 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053013071 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070013072 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
13073 break;
13074
Jeff Johnson295189b2012-06-20 16:38:30 -070013075 default:
13076 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
13077 break;
13078 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013079 pScanInfo = &pHddCtx->scan_info;
13080 if (pScanInfo->mScanPending)
13081 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053013082 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013083 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053013084 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053013085 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053013086 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053013087 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013088#ifdef FEATURE_WLAN_TDLS
13089 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013090 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013091 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013092 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
13093 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013094 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080013095 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013096 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053013097 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013098 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080013099 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070013100 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053013101 status = sme_DeleteTdlsPeerSta(
13102 WLAN_HDD_GET_HAL_CTX(pAdapter),
13103 pAdapter->sessionId,
13104 mac);
13105 if (status != eHAL_STATUS_SUCCESS) {
13106 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
13107 return -EPERM;
13108 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080013109 }
13110 }
13111#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053013112 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013113 status = wlan_hdd_disconnect(pAdapter, reasonCode);
13114 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070013115 {
13116 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013117 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013118 __func__, (int)status );
13119 return -EINVAL;
13120 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013121 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053013122 else
13123 {
13124 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
13125 "called while in %d state", __func__,
13126 pHddStaCtx->conn_info.connState);
13127 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013128 }
13129 else
13130 {
13131 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
13132 }
13133
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013134 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013135 return status;
13136}
13137
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053013138static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
13139 struct net_device *dev,
13140 u16 reason
13141 )
13142{
13143 int ret;
13144 vos_ssr_protect(__func__);
13145 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
13146 vos_ssr_unprotect(__func__);
13147
13148 return ret;
13149}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053013150
Jeff Johnson295189b2012-06-20 16:38:30 -070013151/*
13152 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013153 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070013154 * settings in IBSS mode.
13155 */
13156static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013157 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070013158 struct cfg80211_ibss_params *params
13159 )
13160{
13161 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013162 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070013163 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
13164 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013165
Jeff Johnson295189b2012-06-20 16:38:30 -070013166 ENTER();
13167
13168 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070013169 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070013170
13171 if (params->ie_len && ( NULL != params->ie) )
13172 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013173 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
13174 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070013175 {
13176 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
13177 encryptionType = eCSR_ENCRYPT_TYPE_AES;
13178 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013179 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070013180 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013181 tDot11fIEWPA dot11WPAIE;
13182 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013183 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013184
Wilson Yang00256342013-10-10 23:13:38 -070013185 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013186 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
13187 params->ie_len, DOT11F_EID_WPA);
13188 if ( NULL != ie )
13189 {
13190 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
13191 // Unpack the WPA IE
13192 //Skip past the EID byte and length byte - and four byte WiFi OUI
13193 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
13194 &ie[2+4],
13195 ie[1] - 4,
13196 &dot11WPAIE);
13197 /*Extract the multicast cipher, the encType for unicast
13198 cipher for wpa-none is none*/
13199 encryptionType =
13200 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
13201 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013202 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070013203
Jeff Johnson295189b2012-06-20 16:38:30 -070013204 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
13205
13206 if (0 > status)
13207 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013208 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070013209 __func__);
13210 return status;
13211 }
13212 }
13213
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013214 pWextState->roamProfile.AuthType.authType[0] =
13215 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070013216 eCSR_AUTH_TYPE_OPEN_SYSTEM;
13217
13218 if (params->privacy)
13219 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013220 /* Security enabled IBSS, At this time there is no information available
13221 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070013222 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013223 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070013224 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013225 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070013226 *enable privacy bit in beacons */
13227
13228 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
13229 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070013230 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
13231 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070013232 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
13233 pWextState->roamProfile.EncryptionType.numEntries = 1;
13234 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070013235 return status;
13236}
13237
13238/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013239 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013240 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070013241 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013242static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013243 struct net_device *dev,
13244 struct cfg80211_ibss_params *params
13245 )
13246{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013247 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070013248 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13249 tCsrRoamProfile *pRoamProfile;
13250 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013251 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13252 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013253 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070013254
13255 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013256
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013257 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13258 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
13259 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013260 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013261 "%s: device_mode = %s (%d)", __func__,
13262 hdd_device_modetoString(pAdapter->device_mode),
13263 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013264
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013265 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013266 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013267 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013268 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013269 }
13270
13271 if (NULL == pWextState)
13272 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013273 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070013274 __func__);
13275 return -EIO;
13276 }
13277
Agarwal Ashish51325b52014-06-16 16:50:49 +053013278 if (vos_max_concurrent_connections_reached()) {
13279 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
13280 return -ECONNREFUSED;
13281 }
13282
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053013283 /*Try disconnecting if already in connected state*/
13284 status = wlan_hdd_try_disconnect(pAdapter);
13285 if ( 0 > status)
13286 {
13287 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
13288 " IBSS connection"));
13289 return -EALREADY;
13290 }
13291
Jeff Johnson295189b2012-06-20 16:38:30 -070013292 pRoamProfile = &pWextState->roamProfile;
13293
13294 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
13295 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013296 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013297 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013298 return -EINVAL;
13299 }
13300
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013301 /* BSSID is provided by upper layers hence no need to AUTO generate */
13302 if (NULL != params->bssid) {
13303 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
13304 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
13305 hddLog (VOS_TRACE_LEVEL_ERROR,
13306 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
13307 return -EIO;
13308 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013309 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013310 }
krunal sonie9002db2013-11-25 14:24:17 -080013311 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
13312 {
13313 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
13314 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
13315 {
13316 hddLog (VOS_TRACE_LEVEL_ERROR,
13317 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
13318 return -EIO;
13319 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013320
13321 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080013322 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013323 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080013324 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013325
Jeff Johnson295189b2012-06-20 16:38:30 -070013326 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070013327 if (NULL !=
13328#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
13329 params->chandef.chan)
13330#else
13331 params->channel)
13332#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013333 {
13334 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013335 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
13336 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
13337 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13338 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013339
13340 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013341 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070013342 ieee80211_frequency_to_channel(
13343#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
13344 params->chandef.chan->center_freq);
13345#else
13346 params->channel->center_freq);
13347#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013348
13349 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
13350 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070013351 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013352 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
13353 __func__);
13354 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070013355 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013356
13357 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013358 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013359 if (channelNum == validChan[indx])
13360 {
13361 break;
13362 }
13363 }
13364 if (indx >= numChans)
13365 {
13366 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013367 __func__, channelNum);
13368 return -EINVAL;
13369 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013370 /* Set the Operational Channel */
13371 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
13372 channelNum);
13373 pRoamProfile->ChannelInfo.numOfChannels = 1;
13374 pHddStaCtx->conn_info.operationChannel = channelNum;
13375 pRoamProfile->ChannelInfo.ChannelList =
13376 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070013377 }
13378
13379 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013380 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070013381 if (status < 0)
13382 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013383 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070013384 __func__);
13385 return status;
13386 }
13387
13388 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013389 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013390 params->ssid_len, params->bssid,
13391 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013392
13393 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013394 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013395
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013396 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013397 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013398}
13399
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013400static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
13401 struct net_device *dev,
13402 struct cfg80211_ibss_params *params
13403 )
13404{
13405 int ret = 0;
13406
13407 vos_ssr_protect(__func__);
13408 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
13409 vos_ssr_unprotect(__func__);
13410
13411 return ret;
13412}
13413
Jeff Johnson295189b2012-06-20 16:38:30 -070013414/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013415 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013416 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070013417 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013418static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013419 struct net_device *dev
13420 )
13421{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013422 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013423 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13424 tCsrRoamProfile *pRoamProfile;
13425 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013426 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013427
13428 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013429
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013430 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13431 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
13432 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013433 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013434 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013435 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013436 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013437 }
13438
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013439 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
13440 hdd_device_modetoString(pAdapter->device_mode),
13441 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013442 if (NULL == pWextState)
13443 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013444 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070013445 __func__);
13446 return -EIO;
13447 }
13448
13449 pRoamProfile = &pWextState->roamProfile;
13450
13451 /* Issue disconnect only if interface type is set to IBSS */
13452 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
13453 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013454 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070013455 __func__);
13456 return -EINVAL;
13457 }
13458
13459 /* Issue Disconnect request */
13460 INIT_COMPLETION(pAdapter->disconnect_comp_var);
13461 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
13462 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
13463
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013464 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013465 return 0;
13466}
13467
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013468static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
13469 struct net_device *dev
13470 )
13471{
13472 int ret = 0;
13473
13474 vos_ssr_protect(__func__);
13475 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
13476 vos_ssr_unprotect(__func__);
13477
13478 return ret;
13479}
13480
Jeff Johnson295189b2012-06-20 16:38:30 -070013481/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013482 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070013483 * This function is used to set the phy parameters
13484 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
13485 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013486static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013487 u32 changed)
13488{
13489 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13490 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013491 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013492
13493 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013494
13495 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013496 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
13497 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013498
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013499 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013500 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013501 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013502 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013503 }
13504
Jeff Johnson295189b2012-06-20 16:38:30 -070013505 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
13506 {
13507 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
13508 WNI_CFG_RTS_THRESHOLD_STAMAX :
13509 wiphy->rts_threshold;
13510
13511 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013512 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070013513 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013514 hddLog(VOS_TRACE_LEVEL_ERROR,
13515 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013516 __func__, rts_threshold);
13517 return -EINVAL;
13518 }
13519
13520 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
13521 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013522 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013523 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013524 hddLog(VOS_TRACE_LEVEL_ERROR,
13525 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013526 __func__, rts_threshold);
13527 return -EIO;
13528 }
13529
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013530 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013531 rts_threshold);
13532 }
13533
13534 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
13535 {
13536 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
13537 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
13538 wiphy->frag_threshold;
13539
13540 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013541 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013542 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013543 hddLog(VOS_TRACE_LEVEL_ERROR,
13544 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013545 frag_threshold);
13546 return -EINVAL;
13547 }
13548
13549 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
13550 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013551 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013552 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013553 hddLog(VOS_TRACE_LEVEL_ERROR,
13554 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013555 __func__, frag_threshold);
13556 return -EIO;
13557 }
13558
13559 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
13560 frag_threshold);
13561 }
13562
13563 if ((changed & WIPHY_PARAM_RETRY_SHORT)
13564 || (changed & WIPHY_PARAM_RETRY_LONG))
13565 {
13566 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
13567 wiphy->retry_short :
13568 wiphy->retry_long;
13569
13570 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
13571 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
13572 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013573 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013574 __func__, retry_value);
13575 return -EINVAL;
13576 }
13577
13578 if (changed & WIPHY_PARAM_RETRY_SHORT)
13579 {
13580 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
13581 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013582 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013583 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013584 hddLog(VOS_TRACE_LEVEL_ERROR,
13585 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013586 __func__, retry_value);
13587 return -EIO;
13588 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013589 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013590 __func__, retry_value);
13591 }
13592 else if (changed & WIPHY_PARAM_RETRY_SHORT)
13593 {
13594 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
13595 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013596 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013597 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013598 hddLog(VOS_TRACE_LEVEL_ERROR,
13599 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013600 __func__, retry_value);
13601 return -EIO;
13602 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013603 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013604 __func__, retry_value);
13605 }
13606 }
13607
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013608 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013609 return 0;
13610}
13611
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013612static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
13613 u32 changed)
13614{
13615 int ret;
13616
13617 vos_ssr_protect(__func__);
13618 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
13619 vos_ssr_unprotect(__func__);
13620
13621 return ret;
13622}
13623
Jeff Johnson295189b2012-06-20 16:38:30 -070013624/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013625 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013626 * This function is used to set the txpower
13627 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013628static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013629#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13630 struct wireless_dev *wdev,
13631#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013632#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013633 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013634#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013635 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013636#endif
13637 int dbm)
13638{
13639 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013640 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013641 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13642 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013643 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013644
13645 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013646
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013647 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13648 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
13649 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013650 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013651 if (0 != status)
13652 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013653 return status;
13654 }
13655
13656 hHal = pHddCtx->hHal;
13657
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013658 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
13659 dbm, ccmCfgSetCallback,
13660 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013661 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013662 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013663 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
13664 return -EIO;
13665 }
13666
13667 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
13668 dbm);
13669
13670 switch(type)
13671 {
13672 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
13673 /* Fall through */
13674 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
13675 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
13676 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013677 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
13678 __func__);
13679 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013680 }
13681 break;
13682 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013683 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070013684 __func__);
13685 return -EOPNOTSUPP;
13686 break;
13687 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013688 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
13689 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070013690 return -EIO;
13691 }
13692
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013693 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013694 return 0;
13695}
13696
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013697static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
13698#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13699 struct wireless_dev *wdev,
13700#endif
13701#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13702 enum tx_power_setting type,
13703#else
13704 enum nl80211_tx_power_setting type,
13705#endif
13706 int dbm)
13707{
13708 int ret;
13709 vos_ssr_protect(__func__);
13710 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
13711#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13712 wdev,
13713#endif
13714#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13715 type,
13716#else
13717 type,
13718#endif
13719 dbm);
13720 vos_ssr_unprotect(__func__);
13721
13722 return ret;
13723}
13724
Jeff Johnson295189b2012-06-20 16:38:30 -070013725/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013726 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013727 * This function is used to read the txpower
13728 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013729static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013730#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13731 struct wireless_dev *wdev,
13732#endif
13733 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070013734{
13735
13736 hdd_adapter_t *pAdapter;
13737 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013738 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013739
Jeff Johnsone7245742012-09-05 17:12:55 -070013740 ENTER();
13741
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013742 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013743 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013744 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013745 *dbm = 0;
13746 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013747 }
13748
Jeff Johnson295189b2012-06-20 16:38:30 -070013749 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
13750 if (NULL == pAdapter)
13751 {
13752 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
13753 return -ENOENT;
13754 }
13755
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053013756 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13757 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
13758 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070013759 wlan_hdd_get_classAstats(pAdapter);
13760 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
13761
Jeff Johnsone7245742012-09-05 17:12:55 -070013762 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013763 return 0;
13764}
13765
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013766static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
13767#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13768 struct wireless_dev *wdev,
13769#endif
13770 int *dbm)
13771{
13772 int ret;
13773
13774 vos_ssr_protect(__func__);
13775 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
13776#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13777 wdev,
13778#endif
13779 dbm);
13780 vos_ssr_unprotect(__func__);
13781
13782 return ret;
13783}
13784
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013785static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013786#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13787 const u8* mac,
13788#else
13789 u8* mac,
13790#endif
13791 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070013792{
13793 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13794 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13795 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053013796 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070013797
13798 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
13799 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070013800
13801 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
13802 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
13803 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
13804 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
13805 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
13806 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
13807 tANI_U16 maxRate = 0;
13808 tANI_U16 myRate;
13809 tANI_U16 currentRate = 0;
13810 tANI_U8 maxSpeedMCS = 0;
13811 tANI_U8 maxMCSIdx = 0;
13812 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053013813 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013814 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013815 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013816
Leo Chang6f8870f2013-03-26 18:11:36 -070013817#ifdef WLAN_FEATURE_11AC
13818 tANI_U32 vht_mcs_map;
13819 eDataRate11ACMaxMcs vhtMaxMcs;
13820#endif /* WLAN_FEATURE_11AC */
13821
Jeff Johnsone7245742012-09-05 17:12:55 -070013822 ENTER();
13823
Jeff Johnson295189b2012-06-20 16:38:30 -070013824 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
13825 (0 == ssidlen))
13826 {
13827 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
13828 " Invalid ssidlen, %d", __func__, ssidlen);
13829 /*To keep GUI happy*/
13830 return 0;
13831 }
13832
Mukul Sharma811205f2014-07-09 21:07:30 +053013833 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
13834 {
13835 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13836 "%s: Roaming in progress, so unable to proceed this request", __func__);
13837 return 0;
13838 }
13839
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013840 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013841 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013842 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013843 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013844 }
13845
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053013846 wlan_hdd_get_station_stats(pAdapter);
13847 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070013848
Kiet Lam3b17fc82013-09-27 05:24:08 +053013849 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
13850 sinfo->filled |= STATION_INFO_SIGNAL;
13851
c_hpothu09f19542014-05-30 21:53:31 +053013852 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053013853 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
13854 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053013855 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053013856 {
13857 rate_flags = pAdapter->maxRateFlags;
13858 }
c_hpothu44ff4e02014-05-08 00:13:57 +053013859
Jeff Johnson295189b2012-06-20 16:38:30 -070013860 //convert to the UI units of 100kbps
13861 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
13862
13863#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070013864 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 -070013865 sinfo->signal,
13866 pCfg->reportMaxLinkSpeed,
13867 myRate,
13868 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013869 (int) pCfg->linkSpeedRssiMid,
13870 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070013871 (int) rate_flags,
13872 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013873#endif //LINKSPEED_DEBUG_ENABLED
13874
13875 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
13876 {
13877 // we do not want to necessarily report the current speed
13878 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
13879 {
13880 // report the max possible speed
13881 rssidx = 0;
13882 }
13883 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
13884 {
13885 // report the max possible speed with RSSI scaling
13886 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
13887 {
13888 // report the max possible speed
13889 rssidx = 0;
13890 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013891 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070013892 {
13893 // report middle speed
13894 rssidx = 1;
13895 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013896 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
13897 {
13898 // report middle speed
13899 rssidx = 2;
13900 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013901 else
13902 {
13903 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013904 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070013905 }
13906 }
13907 else
13908 {
13909 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
13910 hddLog(VOS_TRACE_LEVEL_ERROR,
13911 "%s: Invalid value for reportMaxLinkSpeed: %u",
13912 __func__, pCfg->reportMaxLinkSpeed);
13913 rssidx = 0;
13914 }
13915
13916 maxRate = 0;
13917
13918 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013919 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
13920 OperationalRates, &ORLeng))
13921 {
13922 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13923 /*To keep GUI happy*/
13924 return 0;
13925 }
13926
Jeff Johnson295189b2012-06-20 16:38:30 -070013927 for (i = 0; i < ORLeng; i++)
13928 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013929 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013930 {
13931 /* Validate Rate Set */
13932 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
13933 {
13934 currentRate = supported_data_rate[j].supported_rate[rssidx];
13935 break;
13936 }
13937 }
13938 /* Update MAX rate */
13939 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13940 }
13941
13942 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013943 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
13944 ExtendedRates, &ERLeng))
13945 {
13946 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13947 /*To keep GUI happy*/
13948 return 0;
13949 }
13950
Jeff Johnson295189b2012-06-20 16:38:30 -070013951 for (i = 0; i < ERLeng; i++)
13952 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013953 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013954 {
13955 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
13956 {
13957 currentRate = supported_data_rate[j].supported_rate[rssidx];
13958 break;
13959 }
13960 }
13961 /* Update MAX rate */
13962 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13963 }
c_hpothu79aab322014-07-14 21:11:01 +053013964
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013965 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053013966 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013967 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053013968 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070013969 {
c_hpothu79aab322014-07-14 21:11:01 +053013970 if (rate_flags & eHAL_TX_RATE_VHT80)
13971 mode = 2;
13972 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
13973 mode = 1;
13974 else
13975 mode = 0;
13976
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013977 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
13978 MCSRates, &MCSLeng))
13979 {
13980 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13981 /*To keep GUI happy*/
13982 return 0;
13983 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013984 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070013985#ifdef WLAN_FEATURE_11AC
13986 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013987 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070013988 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013989 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013990 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070013991 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070013992 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013993 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013994 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013995 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070013996 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013997 maxMCSIdx = 7;
13998 }
13999 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
14000 {
14001 maxMCSIdx = 8;
14002 }
14003 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
14004 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014005 //VHT20 is supporting 0~8
14006 if (rate_flags & eHAL_TX_RATE_VHT20)
14007 maxMCSIdx = 8;
14008 else
14009 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070014010 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014011
c_hpothu79aab322014-07-14 21:11:01 +053014012 if (0 != rssidx)/*check for scaled */
14013 {
14014 //get middle rate MCS index if rssi=1/2
14015 for (i=0; i <= maxMCSIdx; i++)
14016 {
14017 if (sinfo->signal <= rssiMcsTbl[mode][i])
14018 {
14019 maxMCSIdx = i;
14020 break;
14021 }
14022 }
14023 }
14024
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014025 if (rate_flags & eHAL_TX_RATE_VHT80)
14026 {
14027 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
14028 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
14029 }
14030 else if (rate_flags & eHAL_TX_RATE_VHT40)
14031 {
14032 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
14033 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
14034 }
14035 else if (rate_flags & eHAL_TX_RATE_VHT20)
14036 {
14037 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
14038 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
14039 }
14040
Leo Chang6f8870f2013-03-26 18:11:36 -070014041 maxSpeedMCS = 1;
14042 if (currentRate > maxRate)
14043 {
14044 maxRate = currentRate;
14045 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014046
Leo Chang6f8870f2013-03-26 18:11:36 -070014047 }
14048 else
14049#endif /* WLAN_FEATURE_11AC */
14050 {
14051 if (rate_flags & eHAL_TX_RATE_HT40)
14052 {
14053 rateFlag |= 1;
14054 }
14055 if (rate_flags & eHAL_TX_RATE_SGI)
14056 {
14057 rateFlag |= 2;
14058 }
14059
Girish Gowli01abcee2014-07-31 20:18:55 +053014060 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053014061 if (rssidx == 1 || rssidx == 2)
14062 {
14063 //get middle rate MCS index if rssi=1/2
14064 for (i=0; i <= 7; i++)
14065 {
14066 if (sinfo->signal <= rssiMcsTbl[mode][i])
14067 {
14068 temp = i+1;
14069 break;
14070 }
14071 }
14072 }
c_hpothu79aab322014-07-14 21:11:01 +053014073
14074 for (i = 0; i < MCSLeng; i++)
14075 {
Leo Chang6f8870f2013-03-26 18:11:36 -070014076 for (j = 0; j < temp; j++)
14077 {
14078 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
14079 {
14080 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053014081 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070014082 break;
14083 }
14084 }
14085 if ((j < temp) && (currentRate > maxRate))
14086 {
14087 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070014088 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014089 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053014090 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070014091 }
14092 }
14093
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014094 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
14095 {
14096 maxRate = myRate;
14097 maxSpeedMCS = 1;
14098 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
14099 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014100 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053014101 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070014102 {
14103 maxRate = myRate;
14104 if (rate_flags & eHAL_TX_RATE_LEGACY)
14105 {
14106 maxSpeedMCS = 0;
14107 }
14108 else
14109 {
14110 maxSpeedMCS = 1;
14111 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
14112 }
14113 }
14114
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014115 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070014116 {
14117 sinfo->txrate.legacy = maxRate;
14118#ifdef LINKSPEED_DEBUG_ENABLED
14119 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
14120#endif //LINKSPEED_DEBUG_ENABLED
14121 }
14122 else
14123 {
14124 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070014125#ifdef WLAN_FEATURE_11AC
14126 sinfo->txrate.nss = 1;
14127 if (rate_flags & eHAL_TX_RATE_VHT80)
14128 {
14129 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014130 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070014131 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014132 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070014133 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014134 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14135 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14136 }
14137 else if (rate_flags & eHAL_TX_RATE_VHT20)
14138 {
14139 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14140 }
14141#endif /* WLAN_FEATURE_11AC */
14142 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
14143 {
14144 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
14145 if (rate_flags & eHAL_TX_RATE_HT40)
14146 {
14147 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14148 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014149 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014150 if (rate_flags & eHAL_TX_RATE_SGI)
14151 {
14152 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
14153 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053014154
Jeff Johnson295189b2012-06-20 16:38:30 -070014155#ifdef LINKSPEED_DEBUG_ENABLED
14156 pr_info("Reporting MCS rate %d flags %x\n",
14157 sinfo->txrate.mcs,
14158 sinfo->txrate.flags );
14159#endif //LINKSPEED_DEBUG_ENABLED
14160 }
14161 }
14162 else
14163 {
14164 // report current rate instead of max rate
14165
14166 if (rate_flags & eHAL_TX_RATE_LEGACY)
14167 {
14168 //provide to the UI in units of 100kbps
14169 sinfo->txrate.legacy = myRate;
14170#ifdef LINKSPEED_DEBUG_ENABLED
14171 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
14172#endif //LINKSPEED_DEBUG_ENABLED
14173 }
14174 else
14175 {
14176 //must be MCS
14177 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070014178#ifdef WLAN_FEATURE_11AC
14179 sinfo->txrate.nss = 1;
14180 if (rate_flags & eHAL_TX_RATE_VHT80)
14181 {
14182 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
14183 }
14184 else
14185#endif /* WLAN_FEATURE_11AC */
14186 {
14187 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
14188 }
Jeff Johnson295189b2012-06-20 16:38:30 -070014189 if (rate_flags & eHAL_TX_RATE_SGI)
14190 {
14191 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
14192 }
14193 if (rate_flags & eHAL_TX_RATE_HT40)
14194 {
14195 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
14196 }
Leo Chang6f8870f2013-03-26 18:11:36 -070014197#ifdef WLAN_FEATURE_11AC
14198 else if (rate_flags & eHAL_TX_RATE_VHT80)
14199 {
14200 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
14201 }
14202#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070014203#ifdef LINKSPEED_DEBUG_ENABLED
14204 pr_info("Reporting actual MCS rate %d flags %x\n",
14205 sinfo->txrate.mcs,
14206 sinfo->txrate.flags );
14207#endif //LINKSPEED_DEBUG_ENABLED
14208 }
14209 }
14210 sinfo->filled |= STATION_INFO_TX_BITRATE;
14211
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070014212 sinfo->tx_packets =
14213 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
14214 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
14215 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
14216 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
14217
14218 sinfo->tx_retries =
14219 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
14220 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
14221 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
14222 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
14223
14224 sinfo->tx_failed =
14225 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
14226 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
14227 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
14228 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
14229
14230 sinfo->filled |=
14231 STATION_INFO_TX_PACKETS |
14232 STATION_INFO_TX_RETRIES |
14233 STATION_INFO_TX_FAILED;
14234
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014235 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14236 TRACE_CODE_HDD_CFG80211_GET_STA,
14237 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070014238 EXIT();
14239 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070014240}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014241#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14242static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
14243 const u8* mac, struct station_info *sinfo)
14244#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014245static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
14246 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014247#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014248{
14249 int ret;
14250
14251 vos_ssr_protect(__func__);
14252 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
14253 vos_ssr_unprotect(__func__);
14254
14255 return ret;
14256}
14257
14258static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070014259 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070014260{
14261 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014262 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070014263 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014264 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014265
Jeff Johnsone7245742012-09-05 17:12:55 -070014266 ENTER();
14267
Jeff Johnson295189b2012-06-20 16:38:30 -070014268 if (NULL == pAdapter)
14269 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014270 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014271 return -ENODEV;
14272 }
14273
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014274 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14275 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
14276 pAdapter->sessionId, timeout));
14277
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014278 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014279 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014280 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014281 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014282 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014283 }
14284
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014285 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
14286 (TRUE == pHddCtx->hdd_wlan_suspended) &&
14287 (pHddCtx->cfg_ini->fhostArpOffload) &&
14288 (eConnectionState_Associated ==
14289 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
14290 {
Amar Singhald53568e2013-09-26 11:03:45 -070014291
14292 hddLog(VOS_TRACE_LEVEL_INFO,
14293 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053014294 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014295 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14296 {
14297 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080014298 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053014299 __func__, vos_status);
14300 }
14301 }
14302
Jeff Johnson295189b2012-06-20 16:38:30 -070014303 /**The get power cmd from the supplicant gets updated by the nl only
14304 *on successful execution of the function call
14305 *we are oppositely mapped w.r.t mode in the driver
14306 **/
14307 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
14308
14309 if (VOS_STATUS_E_FAILURE == vos_status)
14310 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053014311 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14312 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014313 return -EINVAL;
14314 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014315 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014316 return 0;
14317}
14318
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014319static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
14320 struct net_device *dev, bool mode, int timeout)
14321{
14322 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014323
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014324 vos_ssr_protect(__func__);
14325 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
14326 vos_ssr_unprotect(__func__);
14327
14328 return ret;
14329}
Jeff Johnson295189b2012-06-20 16:38:30 -070014330#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014331static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
14332 struct net_device *netdev,
14333 u8 key_index)
14334{
14335 ENTER();
14336 return 0;
14337}
14338
Jeff Johnson295189b2012-06-20 16:38:30 -070014339static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014340 struct net_device *netdev,
14341 u8 key_index)
14342{
14343 int ret;
14344 vos_ssr_protect(__func__);
14345 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
14346 vos_ssr_unprotect(__func__);
14347 return ret;
14348}
14349#endif //LINUX_VERSION_CODE
14350
14351#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
14352static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
14353 struct net_device *dev,
14354 struct ieee80211_txq_params *params)
14355{
14356 ENTER();
14357 return 0;
14358}
14359#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14360static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
14361 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070014362{
Jeff Johnsone7245742012-09-05 17:12:55 -070014363 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070014364 return 0;
14365}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014366#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070014367
14368#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
14369static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014370 struct net_device *dev,
14371 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070014372{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014373 int ret;
14374
14375 vos_ssr_protect(__func__);
14376 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
14377 vos_ssr_unprotect(__func__);
14378 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014379}
14380#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14381static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
14382 struct ieee80211_txq_params *params)
14383{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014384 int ret;
14385
14386 vos_ssr_protect(__func__);
14387 ret = __wlan_hdd_set_txq_params(wiphy, params);
14388 vos_ssr_unprotect(__func__);
14389 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014390}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014391#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014392
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014393static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014394 struct net_device *dev,
14395 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070014396{
14397 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014398 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014399 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014400 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014401 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014402 v_CONTEXT_t pVosContext = NULL;
14403 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014404
Jeff Johnsone7245742012-09-05 17:12:55 -070014405 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014406
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014407 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070014408 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014409 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014410 return -EINVAL;
14411 }
14412
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014413 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14414 TRACE_CODE_HDD_CFG80211_DEL_STA,
14415 pAdapter->sessionId, pAdapter->device_mode));
14416
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014417 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14418 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014419 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014420 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014421 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014422 }
14423
Jeff Johnson295189b2012-06-20 16:38:30 -070014424 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014425 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014426 )
14427 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014428 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14429 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14430 if(pSapCtx == NULL){
14431 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14432 FL("psapCtx is NULL"));
14433 return -ENOENT;
14434 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014435 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070014436 {
14437 v_U16_t i;
14438 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
14439 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014440 if ((pSapCtx->aStaInfo[i].isUsed) &&
14441 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070014442 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014443 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014444 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014445 ETHER_ADDR_LEN);
14446
Jeff Johnson295189b2012-06-20 16:38:30 -070014447 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014448 "%s: Delete STA with MAC::"
14449 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014450 __func__,
14451 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
14452 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070014453 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014454 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014455 }
14456 }
14457 }
14458 else
14459 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014460
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014461 vos_status = hdd_softap_GetStaId(pAdapter,
14462 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014463 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14464 {
14465 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014466 "%s: Skip this DEL STA as this is not used::"
14467 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014468 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014469 return -ENOENT;
14470 }
14471
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014472 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014473 {
14474 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014475 "%s: Skip this DEL STA as deauth is in progress::"
14476 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014477 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014478 return -ENOENT;
14479 }
14480
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014481 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014482
Jeff Johnson295189b2012-06-20 16:38:30 -070014483 hddLog(VOS_TRACE_LEVEL_INFO,
14484 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080014485 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014486 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014487 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014488
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014489 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014490 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14491 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014492 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014493 hddLog(VOS_TRACE_LEVEL_INFO,
14494 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080014495 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014496 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014497 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014498 return -ENOENT;
14499 }
14500
Jeff Johnson295189b2012-06-20 16:38:30 -070014501 }
14502 }
14503
14504 EXIT();
14505
14506 return 0;
14507}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014508
14509#ifdef CFG80211_DEL_STA_V2
14510static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14511 struct net_device *dev,
14512 struct station_del_parameters *param)
14513#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014514#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14515static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14516 struct net_device *dev, const u8 *mac)
14517#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014518static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14519 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014520#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014521#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014522{
14523 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014524 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070014525
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014526 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014527
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014528#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014529 if (NULL == param) {
14530 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014531 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014532 return -EINVAL;
14533 }
14534
14535 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
14536 param->subtype, &delStaParams);
14537
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014538#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053014539 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014540 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014541#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014542 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
14543
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014544 vos_ssr_unprotect(__func__);
14545
14546 return ret;
14547}
14548
14549static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014550 struct net_device *dev,
14551#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14552 const u8 *mac,
14553#else
14554 u8 *mac,
14555#endif
14556 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014557{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014558 hdd_adapter_t *pAdapter;
14559 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014560 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014561#ifdef FEATURE_WLAN_TDLS
14562 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014563
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014564 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014565
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014566 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14567 if (NULL == pAdapter)
14568 {
14569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14570 "%s: Adapter is NULL",__func__);
14571 return -EINVAL;
14572 }
14573 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14574 status = wlan_hdd_validate_context(pHddCtx);
14575 if (0 != status)
14576 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014577 return status;
14578 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014579
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014580 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14581 TRACE_CODE_HDD_CFG80211_ADD_STA,
14582 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014583 mask = params->sta_flags_mask;
14584
14585 set = params->sta_flags_set;
14586
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014587 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014588 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
14589 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014590
14591 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
14592 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014593 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014594 }
14595 }
14596#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014597 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014598 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014599}
14600
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014601#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14602static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14603 struct net_device *dev, const u8 *mac,
14604 struct station_parameters *params)
14605#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014606static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14607 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014608#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014609{
14610 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014611
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014612 vos_ssr_protect(__func__);
14613 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
14614 vos_ssr_unprotect(__func__);
14615
14616 return ret;
14617}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014618#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070014619
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014620static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070014621 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014622{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014623 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14624 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014625 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014626 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014627 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014628 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070014629
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014630 ENTER();
14631
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014632 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014633 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014634 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014635 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014636 return -EINVAL;
14637 }
14638
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014639 if (!pmksa) {
14640 hddLog(LOGE, FL("pmksa is NULL"));
14641 return -EINVAL;
14642 }
14643
14644 if (!pmksa->bssid || !pmksa->pmkid) {
14645 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
14646 pmksa->bssid, pmksa->pmkid);
14647 return -EINVAL;
14648 }
14649
14650 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
14651 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14652
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014653 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14654 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014655 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014656 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014657 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014658 }
14659
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014660 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014661 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14662
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014663 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
14664 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014665
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014666 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014667 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014668 &pmk_id, 1, FALSE);
14669
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014670 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14671 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
14672 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014673
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014674 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014675 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014676}
14677
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014678static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
14679 struct cfg80211_pmksa *pmksa)
14680{
14681 int ret;
14682
14683 vos_ssr_protect(__func__);
14684 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
14685 vos_ssr_unprotect(__func__);
14686
14687 return ret;
14688}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014689
Wilson Yang6507c4e2013-10-01 20:11:19 -070014690
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014691static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070014692 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014693{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014694 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14695 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014696 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014697 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014698
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014699 ENTER();
14700
Wilson Yang6507c4e2013-10-01 20:11:19 -070014701 /* Validate pAdapter */
14702 if (NULL == pAdapter)
14703 {
14704 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
14705 return -EINVAL;
14706 }
14707
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014708 if (!pmksa) {
14709 hddLog(LOGE, FL("pmksa is NULL"));
14710 return -EINVAL;
14711 }
14712
14713 if (!pmksa->bssid) {
14714 hddLog(LOGE, FL("pmksa->bssid is NULL"));
14715 return -EINVAL;
14716 }
14717
Kiet Lam98c46a12014-10-31 15:34:57 -070014718 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
14719 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14720
Wilson Yang6507c4e2013-10-01 20:11:19 -070014721 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14722 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014723 if (0 != status)
14724 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014725 return status;
14726 }
14727
14728 /*Retrieve halHandle*/
14729 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14730
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014731 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14732 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
14733 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014734 /* Delete the PMKID CSR cache */
14735 if (eHAL_STATUS_SUCCESS !=
14736 sme_RoamDelPMKIDfromCache(halHandle,
14737 pAdapter->sessionId, pmksa->bssid, FALSE)) {
14738 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
14739 MAC_ADDR_ARRAY(pmksa->bssid));
14740 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014741 }
14742
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014743 EXIT();
14744 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014745}
14746
Wilson Yang6507c4e2013-10-01 20:11:19 -070014747
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014748static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
14749 struct cfg80211_pmksa *pmksa)
14750{
14751 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014752
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014753 vos_ssr_protect(__func__);
14754 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
14755 vos_ssr_unprotect(__func__);
14756
14757 return ret;
14758
14759}
14760
14761static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014762{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014763 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14764 tHalHandle halHandle;
14765 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014766 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014767
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014768 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070014769
14770 /* Validate pAdapter */
14771 if (NULL == pAdapter)
14772 {
14773 hddLog(VOS_TRACE_LEVEL_ERROR,
14774 "%s: Invalid Adapter" ,__func__);
14775 return -EINVAL;
14776 }
14777
14778 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14779 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014780 if (0 != status)
14781 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014782 return status;
14783 }
14784
14785 /*Retrieve halHandle*/
14786 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14787
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014788 /* Flush the PMKID cache in CSR */
14789 if (eHAL_STATUS_SUCCESS !=
14790 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
14791 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
14792 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014793 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014794 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080014795 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014796}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014797
14798static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
14799{
14800 int ret;
14801
14802 vos_ssr_protect(__func__);
14803 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
14804 vos_ssr_unprotect(__func__);
14805
14806 return ret;
14807}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014808#endif
14809
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014810#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014811static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14812 struct net_device *dev,
14813 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014814{
14815 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14816 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014817 hdd_context_t *pHddCtx;
14818 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014819
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014820 ENTER();
14821
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014822 if (NULL == pAdapter)
14823 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014824 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014825 return -ENODEV;
14826 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014827 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14828 ret = wlan_hdd_validate_context(pHddCtx);
14829 if (0 != ret)
14830 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014831 return ret;
14832 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014833 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014834 if (NULL == pHddStaCtx)
14835 {
14836 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
14837 return -EINVAL;
14838 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014839
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014840 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14841 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
14842 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014843 // Added for debug on reception of Re-assoc Req.
14844 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
14845 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014846 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014847 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080014848 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014849 }
14850
14851#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080014852 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014853 ftie->ie_len);
14854#endif
14855
14856 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014857 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
14858 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014859 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014860
14861 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014862 return 0;
14863}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014864
14865static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14866 struct net_device *dev,
14867 struct cfg80211_update_ft_ies_params *ftie)
14868{
14869 int ret;
14870
14871 vos_ssr_protect(__func__);
14872 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
14873 vos_ssr_unprotect(__func__);
14874
14875 return ret;
14876}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014877#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014878
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014879#ifdef FEATURE_WLAN_SCAN_PNO
14880
14881void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
14882 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
14883{
14884 int ret;
14885 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
14886 hdd_context_t *pHddCtx;
14887
Nirav Shah80830bf2013-12-31 16:35:12 +053014888 ENTER();
14889
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014890 if (NULL == pAdapter)
14891 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014892 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014893 "%s: HDD adapter is Null", __func__);
14894 return ;
14895 }
14896
14897 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14898 if (NULL == pHddCtx)
14899 {
14900 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14901 "%s: HDD context is Null!!!", __func__);
14902 return ;
14903 }
14904
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014905 spin_lock(&pHddCtx->schedScan_lock);
14906 if (TRUE == pHddCtx->isWiphySuspended)
14907 {
14908 pHddCtx->isSchedScanUpdatePending = TRUE;
14909 spin_unlock(&pHddCtx->schedScan_lock);
14910 hddLog(VOS_TRACE_LEVEL_INFO,
14911 "%s: Update cfg80211 scan database after it resume", __func__);
14912 return ;
14913 }
14914 spin_unlock(&pHddCtx->schedScan_lock);
14915
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014916 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
14917
14918 if (0 > ret)
14919 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
14920
14921 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014922 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14923 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014924}
14925
14926/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014927 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014928 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014929 */
14930static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
14931{
14932 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14933 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014934 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014935 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14936 int status = 0;
14937 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
14938
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014939 /* The current firmware design does not allow PNO during any
14940 * active sessions. Hence, determine the active sessions
14941 * and return a failure.
14942 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014943 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
14944 {
14945 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014946 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014947
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014948 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
14949 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
14950 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
14951 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
14952 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053014953 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014954 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014955 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014956 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014957 }
14958 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14959 pAdapterNode = pNext;
14960 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014961 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014962}
14963
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014964void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
14965{
14966 hdd_adapter_t *pAdapter = callbackContext;
14967 hdd_context_t *pHddCtx;
14968
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014969 ENTER();
14970
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014971 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
14972 {
14973 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14974 FL("Invalid adapter or adapter has invalid magic"));
14975 return;
14976 }
14977
14978 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14979 if (0 != wlan_hdd_validate_context(pHddCtx))
14980 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014981 return;
14982 }
14983
c_hpothub53c45d2014-08-18 16:53:14 +053014984 if (VOS_STATUS_SUCCESS != status)
14985 {
14986 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014987 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053014988 pHddCtx->isPnoEnable = FALSE;
14989 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014990
14991 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
14992 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014993 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014994}
14995
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014996/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014997 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
14998 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014999 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015000static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015001 struct net_device *dev, struct cfg80211_sched_scan_request *request)
15002{
15003 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015004 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015005 hdd_context_t *pHddCtx;
15006 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015007 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053015008 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
15009 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015010 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
15011 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015012 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015013 hdd_config_t *pConfig = NULL;
15014 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015015
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015016 ENTER();
15017
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015018 if (NULL == pAdapter)
15019 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015020 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015021 "%s: HDD adapter is Null", __func__);
15022 return -ENODEV;
15023 }
15024
15025 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015026 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015027
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015028 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015029 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015030 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015031 }
15032
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015033 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015034 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15035 if (NULL == hHal)
15036 {
15037 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15038 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015039 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015040 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015041 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15042 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
15043 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053015044 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015045 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053015046 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053015047 {
15048 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15049 "%s: aborting the existing scan is unsuccessfull", __func__);
15050 return -EBUSY;
15051 }
15052
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015053 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015054 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053015055 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053015056 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053015057 return -EBUSY;
15058 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015059
c_hpothu37f21312014-04-09 21:49:54 +053015060 if (TRUE == pHddCtx->isPnoEnable)
15061 {
15062 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
15063 FL("already PNO is enabled"));
15064 return -EBUSY;
15065 }
c_hpothu225aa7c2014-10-22 17:45:13 +053015066
15067 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
15068 {
15069 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15070 "%s: abort ROC failed ", __func__);
15071 return -EBUSY;
15072 }
15073
c_hpothu37f21312014-04-09 21:49:54 +053015074 pHddCtx->isPnoEnable = TRUE;
15075
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015076 pnoRequest.enable = 1; /*Enable PNO */
15077 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015078
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015079 if (( !pnoRequest.ucNetworksCount ) ||
15080 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015081 {
15082 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015083 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015084 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015085 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015086 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015087 goto error;
15088 }
15089
15090 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
15091 {
15092 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015093 "%s: Incorrect number of channels %d",
15094 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015095 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015096 goto error;
15097 }
15098
15099 /* Framework provides one set of channels(all)
15100 * common for all saved profile */
15101 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
15102 channels_allowed, &num_channels_allowed))
15103 {
15104 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15105 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015106 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015107 goto error;
15108 }
15109 /* Checking each channel against allowed channel list */
15110 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053015111 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015112 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015113 char chList [(request->n_channels*5)+1];
15114 int len;
15115 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015116 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015117 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015118 {
Nirav Shah80830bf2013-12-31 16:35:12 +053015119 if (request->channels[i]->hw_value == channels_allowed[indx])
15120 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015121 if ((!pConfig->enableDFSPnoChnlScan) &&
15122 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
15123 {
15124 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15125 "%s : Dropping DFS channel : %d",
15126 __func__,channels_allowed[indx]);
15127 num_ignore_dfs_ch++;
15128 break;
15129 }
15130
Nirav Shah80830bf2013-12-31 16:35:12 +053015131 valid_ch[num_ch++] = request->channels[i]->hw_value;
15132 len += snprintf(chList+len, 5, "%d ",
15133 request->channels[i]->hw_value);
15134 break ;
15135 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015136 }
15137 }
Nirav Shah80830bf2013-12-31 16:35:12 +053015138 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015139
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053015140 /*If all channels are DFS and dropped, then ignore the PNO request*/
15141 if (num_ignore_dfs_ch == request->n_channels)
15142 {
15143 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15144 "%s : All requested channels are DFS channels", __func__);
15145 ret = -EINVAL;
15146 goto error;
15147 }
15148 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015149
15150 pnoRequest.aNetworks =
15151 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15152 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015153 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015154 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15155 FL("failed to allocate memory aNetworks %u"),
15156 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15157 goto error;
15158 }
15159 vos_mem_zero(pnoRequest.aNetworks,
15160 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
15161
15162 /* Filling per profile params */
15163 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
15164 {
15165 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015166 request->match_sets[i].ssid.ssid_len;
15167
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015168 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
15169 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015170 {
15171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015172 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015173 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015174 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015175 goto error;
15176 }
15177
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015178 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015179 request->match_sets[i].ssid.ssid,
15180 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053015181 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15182 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015183 i, pnoRequest.aNetworks[i].ssId.ssId);
15184 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
15185 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
15186 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015187
15188 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015189 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
15190 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015191
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015192 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015193 }
15194
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015195 for (i = 0; i < request->n_ssids; i++)
15196 {
15197 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015198 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015199 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015200 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015201 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015202 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015203 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015204 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015205 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015206 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053015207 break;
15208 }
15209 j++;
15210 }
15211 }
15212 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15213 "Number of hidden networks being Configured = %d",
15214 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080015216 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015217
15218 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
15219 if (pnoRequest.p24GProbeTemplate == NULL)
15220 {
15221 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15222 FL("failed to allocate memory p24GProbeTemplate %u"),
15223 SIR_PNO_MAX_PB_REQ_SIZE);
15224 goto error;
15225 }
15226
15227 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
15228 if (pnoRequest.p5GProbeTemplate == NULL)
15229 {
15230 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
15231 FL("failed to allocate memory p5GProbeTemplate %u"),
15232 SIR_PNO_MAX_PB_REQ_SIZE);
15233 goto error;
15234 }
15235
15236 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
15237 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
15238
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053015239 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
15240 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015241 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015242 pnoRequest.us24GProbeTemplateLen = request->ie_len;
15243 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
15244 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015245
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015246 pnoRequest.us5GProbeTemplateLen = request->ie_len;
15247 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
15248 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053015249 }
15250
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015251 /* Driver gets only one time interval which is hardcoded in
15252 * supplicant for 10000ms. Taking power consumption into account 6 timers
15253 * will be used, Timervalue is increased exponentially i.e 10,20,40,
15254 * 80,160,320 secs. And number of scan cycle for each timer
15255 * is configurable through INI param gPNOScanTimerRepeatValue.
15256 * If it is set to 0 only one timer will be used and PNO scan cycle
15257 * will be repeated after each interval specified by supplicant
15258 * till PNO is disabled.
15259 */
15260 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015261 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015262 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015263 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015264 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
15265
15266 tempInterval = (request->interval)/1000;
15267 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15268 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
15269 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015270 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015271 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015272 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015273 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015274 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015275 tempInterval *= 2;
15276 }
15277 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015278 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053015279
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015280 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015281
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015282 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015283 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
15284 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015285 pAdapter->pno_req_status = 0;
15286
Nirav Shah80830bf2013-12-31 16:35:12 +053015287 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15288 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015289 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
15290 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053015291
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015292 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015293 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015294 hdd_cfg80211_sched_scan_done_callback, pAdapter);
15295 if (eHAL_STATUS_SUCCESS != status)
15296 {
15297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053015298 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015299 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015300 goto error;
15301 }
15302
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015303 ret = wait_for_completion_timeout(
15304 &pAdapter->pno_comp_var,
15305 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
15306 if (0 >= ret)
15307 {
15308 // Did not receive the response for PNO enable in time.
15309 // Assuming the PNO enable was success.
15310 // Returning error from here, because we timeout, results
15311 // in side effect of Wifi (Wifi Setting) not to work.
15312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15313 FL("Timed out waiting for PNO to be Enabled"));
15314 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015315 }
15316
15317 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053015318 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015319
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015320error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15322 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053015323 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015324 if (pnoRequest.aNetworks)
15325 vos_mem_free(pnoRequest.aNetworks);
15326 if (pnoRequest.p24GProbeTemplate)
15327 vos_mem_free(pnoRequest.p24GProbeTemplate);
15328 if (pnoRequest.p5GProbeTemplate)
15329 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015330
15331 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015332 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015333}
15334
15335/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015336 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
15337 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015338 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015339static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
15340 struct net_device *dev, struct cfg80211_sched_scan_request *request)
15341{
15342 int ret;
15343
15344 vos_ssr_protect(__func__);
15345 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
15346 vos_ssr_unprotect(__func__);
15347
15348 return ret;
15349}
15350
15351/*
15352 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
15353 * Function to disable PNO
15354 */
15355static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015356 struct net_device *dev)
15357{
15358 eHalStatus status = eHAL_STATUS_FAILURE;
15359 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15360 hdd_context_t *pHddCtx;
15361 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015362 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015363 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015364
15365 ENTER();
15366
15367 if (NULL == pAdapter)
15368 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015370 "%s: HDD adapter is Null", __func__);
15371 return -ENODEV;
15372 }
15373
15374 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015375
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015376 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015377 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015379 "%s: HDD context is Null", __func__);
15380 return -ENODEV;
15381 }
15382
15383 /* The return 0 is intentional when isLogpInProgress and
15384 * isLoadUnloadInProgress. We did observe a crash due to a return of
15385 * failure in sched_scan_stop , especially for a case where the unload
15386 * of the happens at the same time. The function __cfg80211_stop_sched_scan
15387 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
15388 * success. If it returns a failure , then its next invocation due to the
15389 * clean up of the second interface will have the dev pointer corresponding
15390 * to the first one leading to a crash.
15391 */
15392 if (pHddCtx->isLogpInProgress)
15393 {
15394 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15395 "%s: LOGP in Progress. Ignore!!!", __func__);
15396 return ret;
15397 }
15398
Mihir Shete18156292014-03-11 15:38:30 +053015399 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015400 {
15401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15402 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15403 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015404 }
15405
15406 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15407 if (NULL == hHal)
15408 {
15409 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15410 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015411 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015412 }
15413
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015414 pnoRequest.enable = 0; /* Disable PNO */
15415 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015416
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015417 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15418 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
15419 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015420 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015421 pAdapter->sessionId,
15422 NULL, pAdapter);
15423 if (eHAL_STATUS_SUCCESS != status)
15424 {
15425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15426 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015427 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015428 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015429 }
c_hpothu37f21312014-04-09 21:49:54 +053015430 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015431
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015432error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015433 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015434 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015435
15436 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015437 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015438}
15439
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015440/*
15441 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
15442 * NL interface to disable PNO
15443 */
15444static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
15445 struct net_device *dev)
15446{
15447 int ret;
15448
15449 vos_ssr_protect(__func__);
15450 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
15451 vos_ssr_unprotect(__func__);
15452
15453 return ret;
15454}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015455#endif /*FEATURE_WLAN_SCAN_PNO*/
15456
15457
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015458#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015459#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015460static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15461 struct net_device *dev,
15462 u8 *peer, u8 action_code,
15463 u8 dialog_token,
15464 u16 status_code, u32 peer_capability,
15465 const u8 *buf, size_t len)
15466#else /* TDLS_MGMT_VERSION2 */
15467#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
15468static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15469 struct net_device *dev,
15470 const u8 *peer, u8 action_code,
15471 u8 dialog_token, u16 status_code,
15472 u32 peer_capability, bool initiator,
15473 const u8 *buf, size_t len)
15474#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
15475static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15476 struct net_device *dev,
15477 const u8 *peer, u8 action_code,
15478 u8 dialog_token, u16 status_code,
15479 u32 peer_capability, const u8 *buf,
15480 size_t len)
15481#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
15482static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15483 struct net_device *dev,
15484 u8 *peer, u8 action_code,
15485 u8 dialog_token,
15486 u16 status_code, u32 peer_capability,
15487 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015488#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015489static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15490 struct net_device *dev,
15491 u8 *peer, u8 action_code,
15492 u8 dialog_token,
15493 u16 status_code, const u8 *buf,
15494 size_t len)
15495#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015496#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015497{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015498 hdd_adapter_t *pAdapter;
15499 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015500 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070015501 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080015502 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070015503 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015504 int ret;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015505#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015506 u32 peer_capability = 0;
15507#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015508 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015509 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015510
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015511 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15512 if (NULL == pAdapter)
15513 {
15514 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15515 "%s: Adapter is NULL",__func__);
15516 return -EINVAL;
15517 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015518 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15519 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
15520 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015521
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015522 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015523 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015524 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015525 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015526 "Invalid arguments");
15527 return -EINVAL;
15528 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015529
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015530 if (pHddCtx->isLogpInProgress)
15531 {
15532 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15533 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053015534 wlan_hdd_tdls_set_link_status(pAdapter,
15535 peer,
15536 eTDLS_LINK_IDLE,
15537 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015538 return -EBUSY;
15539 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015540
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015541 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
15542 {
15543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15544 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15545 return -EAGAIN;
15546 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015547
Hoonki Lee27511902013-03-14 18:19:06 -070015548 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015549 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015550 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015551 "%s: TDLS mode is disabled OR not enabled in FW."
15552 MAC_ADDRESS_STR " action %d declined.",
15553 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015554 return -ENOTSUPP;
15555 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015556
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015557 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15558
15559 if( NULL == pHddStaCtx )
15560 {
15561 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15562 "%s: HDD station context NULL ",__func__);
15563 return -EINVAL;
15564 }
15565
15566 /* STA should be connected and authenticated
15567 * before sending any TDLS frames
15568 */
15569 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15570 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
15571 {
15572 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15573 "STA is not connected or unauthenticated. "
15574 "connState %u, uIsAuthenticated %u",
15575 pHddStaCtx->conn_info.connState,
15576 pHddStaCtx->conn_info.uIsAuthenticated);
15577 return -EAGAIN;
15578 }
15579
Hoonki Lee27511902013-03-14 18:19:06 -070015580 /* other than teardown frame, other mgmt frames are not sent if disabled */
15581 if (SIR_MAC_TDLS_TEARDOWN != action_code)
15582 {
15583 /* if tdls_mode is disabled to respond to peer's request */
15584 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
15585 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015586 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015587 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015588 " TDLS mode is disabled. action %d declined.",
15589 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070015590
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015591 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070015592 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053015593
15594 if (vos_max_concurrent_connections_reached())
15595 {
15596 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15597 return -EINVAL;
15598 }
Hoonki Lee27511902013-03-14 18:19:06 -070015599 }
15600
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015601 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
15602 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053015603 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015604 {
15605 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015606 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015607 " TDLS setup is ongoing. action %d declined.",
15608 __func__, MAC_ADDR_ARRAY(peer), action_code);
15609 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015610 }
15611 }
15612
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015613 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
15614 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080015615 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015616 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15617 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015618 {
15619 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
15620 we return error code at 'add_station()'. Hence we have this
15621 check again in addtion to add_station().
15622 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015623 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015624 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015625 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15626 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015627 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
15628 __func__, MAC_ADDR_ARRAY(peer), action_code,
15629 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053015630 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080015631 }
15632 else
15633 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015634 /* maximum reached. tweak to send error code to peer and return
15635 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015636 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015637 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15638 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015639 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
15640 __func__, MAC_ADDR_ARRAY(peer), status_code,
15641 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070015642 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015643 /* fall through to send setup resp with failure status
15644 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015645 }
15646 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015647 else
15648 {
15649 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053015650 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015651 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015652 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015653 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015654 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
15655 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015656 return -EPERM;
15657 }
15658 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015659 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015660
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015661 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015662 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015663 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
15664 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015665
Hoonki Leea34dd892013-02-05 22:56:02 -080015666 /*Except teardown responder will not be used so just make 0*/
15667 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015668 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080015669 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015670
15671 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015672 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015673
15674 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
15675 responder = pTdlsPeer->is_responder;
15676 else
Hoonki Leea34dd892013-02-05 22:56:02 -080015677 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015678 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015679 "%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 -070015680 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
15681 dialog_token, status_code, len);
15682 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080015683 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015684 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015685
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015686 /* For explicit trigger of DIS_REQ come out of BMPS for
15687 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070015688 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015689 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
15690 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070015691 {
15692 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
15693 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015694 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015695 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015696 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
15697 if (status != VOS_STATUS_SUCCESS) {
15698 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
15699 }
Hoonki Lee14621352013-04-16 17:51:19 -070015700 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015701 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015702 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015703 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
15704 }
15705 }
Hoonki Lee14621352013-04-16 17:51:19 -070015706 }
15707
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015708 /* make sure doesn't call send_mgmt() while it is pending */
15709 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
15710 {
15711 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015712 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015713 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015714 ret = -EBUSY;
15715 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015716 }
15717
15718 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015719 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
15720
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015721 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
15722 pAdapter->sessionId, peer, action_code, dialog_token,
15723 status_code, peer_capability, (tANI_U8 *)buf, len,
15724 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015725
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015726 if (VOS_STATUS_SUCCESS != status)
15727 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015728 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15729 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015730 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015731 ret = -EINVAL;
15732 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015733 }
15734
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015735 if ((SIR_MAC_TDLS_DIS_REQ == action_code) ||
15736 (SIR_MAC_TDLS_DIS_RSP == action_code))
15737 {
15738 /* for DIS_REQ/DIS_RSP, supplicant don't consider the return status.
15739 * So we no need to wait for tdls_mgmt_comp for sending ack status.
15740 */
15741 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15742 "%s: tx done for frm %u", __func__, action_code);
15743 return 0;
15744 }
15745
15746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15747 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
15748 WAIT_TIME_TDLS_MGMT);
15749
Hoonki Leed37cbb32013-04-20 00:31:14 -070015750 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
15751 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
15752
15753 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015754 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070015755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015756 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070015757 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015758 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080015759
15760 if (pHddCtx->isLogpInProgress)
15761 {
15762 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15763 "%s: LOGP in Progress. Ignore!!!", __func__);
15764 return -EAGAIN;
15765 }
15766
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015767 ret = -EINVAL;
15768 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015769 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015770 else
15771 {
15772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15773 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
15774 __func__, rc, pAdapter->mgmtTxCompletionStatus);
15775 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015776
Gopichand Nakkala05922802013-03-14 12:23:19 -070015777 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070015778 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015779 ret = max_sta_failed;
15780 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070015781 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015782
Hoonki Leea34dd892013-02-05 22:56:02 -080015783 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
15784 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015785 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015786 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15787 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015788 }
15789 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
15790 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015791 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015792 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15793 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015794 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015795
15796 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015797
15798tx_failed:
15799 /* add_station will be called before sending TDLS_SETUP_REQ and
15800 * TDLS_SETUP_RSP and as part of add_station driver will enable
15801 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
15802 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
15803 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
15804 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
15805 */
15806
15807 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
15808 (SIR_MAC_TDLS_SETUP_RSP == action_code))
15809 wlan_hdd_tdls_check_bmps(pAdapter);
15810 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015811}
15812
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015813#if TDLS_MGMT_VERSION2
15814static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15815 u8 *peer, u8 action_code, u8 dialog_token,
15816 u16 status_code, u32 peer_capability,
15817 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015818#else /* TDLS_MGMT_VERSION2 */
15819#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
15820static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15821 struct net_device *dev,
15822 const u8 *peer, u8 action_code,
15823 u8 dialog_token, u16 status_code,
15824 u32 peer_capability, bool initiator,
15825 const u8 *buf, size_t len)
15826#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15827static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15828 struct net_device *dev,
15829 const u8 *peer, u8 action_code,
15830 u8 dialog_token, u16 status_code,
15831 u32 peer_capability, const u8 *buf,
15832 size_t len)
15833#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
15834static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15835 struct net_device *dev,
15836 u8 *peer, u8 action_code,
15837 u8 dialog_token,
15838 u16 status_code, u32 peer_capability,
15839 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015840#else
15841static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15842 u8 *peer, u8 action_code, u8 dialog_token,
15843 u16 status_code, const u8 *buf, size_t len)
15844#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015845#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015846{
15847 int ret;
15848
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015849 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015850#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015851 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15852 dialog_token, status_code,
15853 peer_capability, buf, len);
15854#else /* TDLS_MGMT_VERSION2 */
15855#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
15856 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15857 dialog_token, status_code,
15858 peer_capability, initiator,
15859 buf, len);
15860#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
15861 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15862 dialog_token, status_code,
15863 peer_capability, buf, len);
15864#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
15865 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15866 dialog_token, status_code,
15867 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015868#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015869 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15870 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015871#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015872#endif
15873 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015874
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015875 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015876}
Atul Mittal115287b2014-07-08 13:26:33 +053015877
15878int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015879#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15880 const u8 *peer,
15881#else
Atul Mittal115287b2014-07-08 13:26:33 +053015882 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015883#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015884 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053015885 cfg80211_exttdls_callback callback)
15886{
15887
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015888 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053015889 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015890 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053015891 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15892 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
15893 __func__, MAC_ADDR_ARRAY(peer));
15894
15895 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
15896 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
15897
15898 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015899 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
15900 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
15901 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053015902 return -ENOTSUPP;
15903 }
15904
15905 /* To cater the requirement of establishing the TDLS link
15906 * irrespective of the data traffic , get an entry of TDLS peer.
15907 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015908 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015909 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
15910 if (pTdlsPeer == NULL) {
15911 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15912 "%s: peer " MAC_ADDRESS_STR " not existing",
15913 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015914 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015915 return -EINVAL;
15916 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015917 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015918
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053015919 /* check FW TDLS Off Channel capability */
15920 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053015921 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053015922 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015923 {
15924 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
15925 pTdlsPeer->peerParams.global_operating_class =
15926 tdls_peer_params->global_operating_class;
15927 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
15928 pTdlsPeer->peerParams.min_bandwidth_kbps =
15929 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015930 /* check configured channel is valid, non dfs and
15931 * not current operating channel */
15932 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
15933 tdls_peer_params->channel)) &&
15934 (pHddStaCtx) &&
15935 (tdls_peer_params->channel !=
15936 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015937 {
15938 pTdlsPeer->isOffChannelConfigured = TRUE;
15939 }
15940 else
15941 {
15942 pTdlsPeer->isOffChannelConfigured = FALSE;
15943 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15944 "%s: Configured Tdls Off Channel is not valid", __func__);
15945
15946 }
15947 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015948 "%s: tdls_off_channel %d isOffChannelConfigured %d "
15949 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015950 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015951 pTdlsPeer->isOffChannelConfigured,
15952 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015953 }
15954 else
15955 {
15956 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053015957 "%s: TDLS off channel FW capability %d, "
15958 "host capab %d or Invalid TDLS Peer Params", __func__,
15959 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
15960 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015961 }
15962
Atul Mittal115287b2014-07-08 13:26:33 +053015963 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
15964
15965 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15966 " %s TDLS Add Force Peer Failed",
15967 __func__);
15968 return -EINVAL;
15969 }
15970 /*EXT TDLS*/
15971
15972 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
15973 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15974 " %s TDLS set callback Failed",
15975 __func__);
15976 return -EINVAL;
15977 }
15978
15979 return(0);
15980
15981}
15982
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015983int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
15984#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15985 const u8 *peer
15986#else
15987 u8 *peer
15988#endif
15989)
Atul Mittal115287b2014-07-08 13:26:33 +053015990{
15991
15992 hddTdlsPeer_t *pTdlsPeer;
15993 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15994 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15995 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
15996 __func__, MAC_ADDR_ARRAY(peer));
15997
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015998 if (0 != wlan_hdd_validate_context(pHddCtx)) {
15999 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
16000 return -EINVAL;
16001 }
16002
Atul Mittal115287b2014-07-08 13:26:33 +053016003 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
16004 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
16005
16006 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016007 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
16008 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
16009 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053016010 return -ENOTSUPP;
16011 }
16012
16013
16014 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
16015
16016 if ( NULL == pTdlsPeer ) {
16017 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016018 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053016019 __func__, MAC_ADDR_ARRAY(peer));
16020 return -EINVAL;
16021 }
16022 else {
16023 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
16024 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016025 /* if channel switch is configured, reset
16026 the channel for this peer */
16027 if (TRUE == pTdlsPeer->isOffChannelConfigured)
16028 {
16029 pTdlsPeer->peerParams.channel = 0;
16030 pTdlsPeer->isOffChannelConfigured = FALSE;
16031 }
Atul Mittal115287b2014-07-08 13:26:33 +053016032 }
16033
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016034 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
16035 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053016036 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016037 }
Atul Mittal115287b2014-07-08 13:26:33 +053016038
16039 /*EXT TDLS*/
16040
16041 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
16042
16043 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16044 " %s TDLS set callback Failed",
16045 __func__);
16046 return -EINVAL;
16047 }
16048 return(0);
16049
16050}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016051static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016052#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16053 const u8 *peer,
16054#else
16055 u8 *peer,
16056#endif
16057 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016058{
16059 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16060 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016061 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016062 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016063
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016064 ENTER();
16065
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053016066 if (!pAdapter) {
16067 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
16068 return -EINVAL;
16069 }
16070
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016071 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16072 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
16073 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016074 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016075 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080016076 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070016077 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016078 return -EINVAL;
16079 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016080
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016081 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016082 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080016083 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016084 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080016085 }
16086
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016087
16088 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016089 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016090 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080016091 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016092 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
16093 "Cannot process TDLS commands",
16094 pHddCtx->cfg_ini->fEnableTDLSSupport,
16095 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016096 return -ENOTSUPP;
16097 }
16098
16099 switch (oper) {
16100 case NL80211_TDLS_ENABLE_LINK:
16101 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016102 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016103 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016104 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053016105 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016106 tANI_U16 numCurrTdlsPeers = 0;
16107 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016108 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016109
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016110 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16111 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
16112 __func__, MAC_ADDR_ARRAY(peer));
Sunil Dutt41de4e22013-11-14 18:09:02 +053016113 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053016114 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053016115 if ( NULL == pTdlsPeer ) {
16116 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
16117 " (oper %d) not exsting. ignored",
16118 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
16119 return -EINVAL;
16120 }
16121
16122 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16123 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
16124 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
16125 "NL80211_TDLS_ENABLE_LINK");
16126
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070016127 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
16128 {
16129 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
16130 MAC_ADDRESS_STR " failed",
16131 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
16132 return -EINVAL;
16133 }
16134
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053016135 /* before starting tdls connection, set tdls
16136 * off channel established status to default value */
16137 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016138 /* TDLS Off Channel, Disable tdls channel switch,
16139 when there are more than one tdls link */
16140 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053016141 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016142 {
16143 /* get connected peer and send disable tdls off chan */
16144 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016145 if ((connPeer) &&
16146 (connPeer->isOffChannelSupported == TRUE) &&
16147 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016148 {
16149 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16150 "%s: More then one peer connected, Disable "
16151 "TDLS channel switch", __func__);
16152
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016153 connPeer->isOffChannelEstablished = FALSE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016154 ret = sme_SendTdlsChanSwitchReq(
16155 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016156 pAdapter->sessionId,
16157 connPeer->peerMac,
16158 connPeer->peerParams.channel,
16159 TDLS_OFF_CHANNEL_BW_OFFSET,
16160 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016161 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016162 hddLog(VOS_TRACE_LEVEL_ERROR,
16163 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016164 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016165 }
16166 else
16167 {
16168 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16169 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016170 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016171 "isOffChannelConfigured %d",
16172 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016173 (connPeer ? (connPeer->isOffChannelSupported)
16174 : -1),
16175 (connPeer ? (connPeer->isOffChannelConfigured)
16176 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016177 }
16178 }
16179
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016180 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016181 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016182 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053016183
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016184 if (0 != wlan_hdd_tdls_get_link_establish_params(
16185 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016186 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016187 return -EINVAL;
16188 }
16189 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016190
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016191 ret = sme_SendTdlsLinkEstablishParams(
16192 WLAN_HDD_GET_HAL_CTX(pAdapter),
16193 pAdapter->sessionId, peer,
16194 &tdlsLinkEstablishParams);
16195 if (ret != VOS_STATUS_SUCCESS) {
16196 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
16197 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016198 /* Send TDLS peer UAPSD capabilities to the firmware and
16199 * register with the TL on after the response for this operation
16200 * is received .
16201 */
16202 ret = wait_for_completion_interruptible_timeout(
16203 &pAdapter->tdls_link_establish_req_comp,
16204 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
16205 if (ret <= 0)
16206 {
16207 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016208 FL("Link Establish Request Failed Status %ld"),
16209 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053016210 return -EINVAL;
16211 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016212 }
Atul Mittal115287b2014-07-08 13:26:33 +053016213 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
16214 eTDLS_LINK_CONNECTED,
16215 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053016216 staDesc.ucSTAId = pTdlsPeer->staId;
16217 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016218 ret = WLANTL_UpdateTdlsSTAClient(
16219 pHddCtx->pvosContext,
16220 &staDesc);
16221 if (ret != VOS_STATUS_SUCCESS) {
16222 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
16223 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053016224
Gopichand Nakkala471708b2013-06-04 20:03:01 +053016225 /* Mark TDLS client Authenticated .*/
16226 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
16227 pTdlsPeer->staId,
16228 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070016229 if (VOS_STATUS_SUCCESS == status)
16230 {
Hoonki Lee14621352013-04-16 17:51:19 -070016231 if (pTdlsPeer->is_responder == 0)
16232 {
16233 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
Ganesh Kondabattinicbfdc392015-09-11 19:12:59 +053016234 tdlsConnInfo_t *tdlsInfo;
16235
16236 tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
16237
16238 /* Initialize initiator wait callback */
16239 vos_timer_init(
16240 &pTdlsPeer->initiatorWaitTimeoutTimer,
16241 VOS_TIMER_TYPE_SW,
16242 wlan_hdd_tdls_initiator_wait_cb,
16243 tdlsInfo);
Hoonki Lee14621352013-04-16 17:51:19 -070016244
16245 wlan_hdd_tdls_timer_restart(pAdapter,
16246 &pTdlsPeer->initiatorWaitTimeoutTimer,
16247 WAIT_TIME_TDLS_INITIATOR);
16248 /* suspend initiator TX until it receives direct packet from the
16249 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016250 ret = WLANTL_SuspendDataTx(
16251 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
16252 &staId, NULL);
16253 if (ret != VOS_STATUS_SUCCESS) {
16254 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
16255 }
Hoonki Lee14621352013-04-16 17:51:19 -070016256 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016257
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016258 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016259 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016260 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016261 suppChannelLen =
16262 tdlsLinkEstablishParams.supportedChannelsLen;
16263
16264 if ((suppChannelLen > 0) &&
16265 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
16266 {
16267 tANI_U8 suppPeerChannel = 0;
16268 int i = 0;
16269 for (i = 0U; i < suppChannelLen; i++)
16270 {
16271 suppPeerChannel =
16272 tdlsLinkEstablishParams.supportedChannels[i];
16273
16274 pTdlsPeer->isOffChannelSupported = FALSE;
16275 if (suppPeerChannel ==
16276 pTdlsPeer->peerParams.channel)
16277 {
16278 pTdlsPeer->isOffChannelSupported = TRUE;
16279 break;
16280 }
16281 }
16282 }
16283 else
16284 {
16285 pTdlsPeer->isOffChannelSupported = FALSE;
16286 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016287 }
16288 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16289 "%s: TDLS channel switch request for channel "
16290 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016291 "%d isOffChannelSupported %d", __func__,
16292 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016293 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053016294 suppChannelLen,
16295 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053016296
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016297 /* TDLS Off Channel, Enable tdls channel switch,
16298 when their is only one tdls link and it supports */
16299 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
16300 if ((numCurrTdlsPeers == 1) &&
16301 (TRUE == pTdlsPeer->isOffChannelSupported) &&
16302 (TRUE == pTdlsPeer->isOffChannelConfigured))
16303 {
16304 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16305 "%s: Send TDLS channel switch request for channel %d",
16306 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016307
16308 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016309 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
16310 pAdapter->sessionId,
16311 pTdlsPeer->peerMac,
16312 pTdlsPeer->peerParams.channel,
16313 TDLS_OFF_CHANNEL_BW_OFFSET,
16314 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016315 if (ret != VOS_STATUS_SUCCESS) {
16316 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
16317 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016318 }
16319 else
16320 {
16321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16322 "%s: TDLS channel switch request not sent"
16323 " numCurrTdlsPeers %d "
16324 "isOffChannelSupported %d "
16325 "isOffChannelConfigured %d",
16326 __func__, numCurrTdlsPeers,
16327 pTdlsPeer->isOffChannelSupported,
16328 pTdlsPeer->isOffChannelConfigured);
16329 }
16330
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070016331 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016332 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016333
16334 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016335 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
16336 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016337 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016338 int ac;
16339 uint8 ucAc[4] = { WLANTL_AC_VO,
16340 WLANTL_AC_VI,
16341 WLANTL_AC_BK,
16342 WLANTL_AC_BE };
16343 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
16344 for(ac=0; ac < 4; ac++)
16345 {
16346 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
16347 pTdlsPeer->staId, ucAc[ac],
16348 tlTid[ac], tlTid[ac], 0, 0,
16349 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016350 if (status != VOS_STATUS_SUCCESS) {
16351 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
16352 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016353 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016354 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016355 }
16356
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016357 }
16358 break;
16359 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080016360 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016361 tANI_U16 numCurrTdlsPeers = 0;
16362 hddTdlsPeer_t *connPeer = NULL;
16363
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016364 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16365 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
16366 __func__, MAC_ADDR_ARRAY(peer));
16367
Sunil Dutt41de4e22013-11-14 18:09:02 +053016368 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
16369
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016370
Sunil Dutt41de4e22013-11-14 18:09:02 +053016371 if ( NULL == pTdlsPeer ) {
16372 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
16373 " (oper %d) not exsting. ignored",
16374 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
16375 return -EINVAL;
16376 }
16377
16378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16379 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
16380 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
16381 "NL80211_TDLS_DISABLE_LINK");
16382
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016383 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080016384 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016385 long status;
16386
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053016387 /* set tdls off channel status to false for this peer */
16388 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053016389 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
16390 eTDLS_LINK_TEARING,
16391 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
16392 eTDLS_LINK_UNSPECIFIED:
16393 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016394 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
16395
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016396 status = sme_DeleteTdlsPeerSta(
16397 WLAN_HDD_GET_HAL_CTX(pAdapter),
16398 pAdapter->sessionId, peer );
16399 if (status != VOS_STATUS_SUCCESS) {
16400 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
16401 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016402
16403 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
16404 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053016405 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053016406 eTDLS_LINK_IDLE,
16407 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016408 if (status <= 0)
16409 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016410 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16411 "%s: Del station failed status %ld",
16412 __func__, status);
16413 return -EPERM;
16414 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016415
16416 /* TDLS Off Channel, Enable tdls channel switch,
16417 when their is only one tdls link and it supports */
16418 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
16419 if (numCurrTdlsPeers == 1)
16420 {
16421 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
16422 if ((connPeer) &&
16423 (connPeer->isOffChannelSupported == TRUE) &&
16424 (connPeer->isOffChannelConfigured == TRUE))
16425 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016426 connPeer->isOffChannelEstablished = TRUE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016427 status = sme_SendTdlsChanSwitchReq(
16428 WLAN_HDD_GET_HAL_CTX(pAdapter),
16429 pAdapter->sessionId,
16430 connPeer->peerMac,
16431 connPeer->peerParams.channel,
16432 TDLS_OFF_CHANNEL_BW_OFFSET,
16433 TDLS_CHANNEL_SWITCH_ENABLE);
16434 if (status != VOS_STATUS_SUCCESS) {
16435 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
16436 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016437 }
16438 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16439 "%s: TDLS channel switch "
16440 "isOffChannelSupported %d "
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016441 "isOffChannelConfigured %d "
16442 "isOffChannelEstablished %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016443 __func__,
16444 (connPeer ? connPeer->isOffChannelSupported : -1),
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016445 (connPeer ? connPeer->isOffChannelConfigured : -1),
16446 (connPeer ? connPeer->isOffChannelEstablished : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016447 }
16448 else
16449 {
16450 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16451 "%s: TDLS channel switch request not sent "
16452 "numCurrTdlsPeers %d ",
16453 __func__, numCurrTdlsPeers);
16454 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080016455 }
16456 else
16457 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016458 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16459 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080016460 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080016461 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016462 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016463 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053016464 {
Atul Mittal115287b2014-07-08 13:26:33 +053016465 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053016466
Atul Mittal115287b2014-07-08 13:26:33 +053016467 if (0 != status)
16468 {
16469 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016470 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053016471 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053016472 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053016473 break;
16474 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016475 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053016476 {
Atul Mittal115287b2014-07-08 13:26:33 +053016477 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
16478 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016479 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053016480 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053016481
Atul Mittal115287b2014-07-08 13:26:33 +053016482 if (0 != status)
16483 {
16484 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016485 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053016486 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053016487 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053016488 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053016489 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016490 case NL80211_TDLS_DISCOVERY_REQ:
16491 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016492 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016493 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016494 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016495 return -ENOTSUPP;
16496 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16498 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016499 return -ENOTSUPP;
16500 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016501
16502 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016503 return 0;
16504}
Chilam NG571c65a2013-01-19 12:27:36 +053016505
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016506static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016507#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16508 const u8 *peer,
16509#else
16510 u8 *peer,
16511#endif
16512 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016513{
16514 int ret;
16515
16516 vos_ssr_protect(__func__);
16517 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
16518 vos_ssr_unprotect(__func__);
16519
16520 return ret;
16521}
16522
Chilam NG571c65a2013-01-19 12:27:36 +053016523int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
16524 struct net_device *dev, u8 *peer)
16525{
Arif Hussaina7c8e412013-11-20 11:06:42 -080016526 hddLog(VOS_TRACE_LEVEL_INFO,
16527 "tdls send discover req: "MAC_ADDRESS_STR,
16528 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053016529
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016530#if TDLS_MGMT_VERSION2
16531 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16532 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16533#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016534#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
16535 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16536 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
16537#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16538 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16539 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16540#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
16541 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16542 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16543#else
Chilam NG571c65a2013-01-19 12:27:36 +053016544 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16545 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016546#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016547#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053016548}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016549#endif
16550
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016551#ifdef WLAN_FEATURE_GTK_OFFLOAD
16552/*
16553 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
16554 * Callback rountine called upon receiving response for
16555 * get offload info
16556 */
16557void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
16558 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
16559{
16560
16561 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016562 tANI_U8 tempReplayCounter[8];
16563 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016564
16565 ENTER();
16566
16567 if (NULL == pAdapter)
16568 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016569 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016570 "%s: HDD adapter is Null", __func__);
16571 return ;
16572 }
16573
16574 if (NULL == pGtkOffloadGetInfoRsp)
16575 {
16576 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16577 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
16578 return ;
16579 }
16580
16581 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
16582 {
16583 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16584 "%s: wlan Failed to get replay counter value",
16585 __func__);
16586 return ;
16587 }
16588
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016589 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16590 /* Update replay counter */
16591 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
16592 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16593
16594 {
16595 /* changing from little to big endian since supplicant
16596 * works on big endian format
16597 */
16598 int i;
16599 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16600
16601 for (i = 0; i < 8; i++)
16602 {
16603 tempReplayCounter[7-i] = (tANI_U8)p[i];
16604 }
16605 }
16606
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016607 /* Update replay counter to NL */
16608 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016609 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016610}
16611
16612/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016613 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016614 * This function is used to offload GTK rekeying job to the firmware.
16615 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016616int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016617 struct cfg80211_gtk_rekey_data *data)
16618{
16619 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16620 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16621 hdd_station_ctx_t *pHddStaCtx;
16622 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016623 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016624 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016625 eHalStatus status = eHAL_STATUS_FAILURE;
16626
16627 ENTER();
16628
16629 if (NULL == pAdapter)
16630 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016631 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016632 "%s: HDD adapter is Null", __func__);
16633 return -ENODEV;
16634 }
16635
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016636 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16637 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
16638 pAdapter->sessionId, pAdapter->device_mode));
16639
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016640 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016641 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016642 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016643 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016644 }
16645
16646 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16647 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16648 if (NULL == hHal)
16649 {
16650 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16651 "%s: HAL context is Null!!!", __func__);
16652 return -EAGAIN;
16653 }
16654
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016655 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
16656 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
16657 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
16658 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016659 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016660 {
16661 /* changing from big to little endian since driver
16662 * works on little endian format
16663 */
16664 tANI_U8 *p =
16665 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
16666 int i;
16667
16668 for (i = 0; i < 8; i++)
16669 {
16670 p[7-i] = data->replay_ctr[i];
16671 }
16672 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016673
16674 if (TRUE == pHddCtx->hdd_wlan_suspended)
16675 {
16676 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016677 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
16678 sizeof (tSirGtkOffloadParams));
16679 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016680 pAdapter->sessionId);
16681
16682 if (eHAL_STATUS_SUCCESS != status)
16683 {
16684 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16685 "%s: sme_SetGTKOffload failed, returned %d",
16686 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016687
16688 /* Need to clear any trace of key value in the memory.
16689 * Thus zero out the memory even though it is local
16690 * variable.
16691 */
16692 vos_mem_zero(&hddGtkOffloadReqParams,
16693 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016694 return status;
16695 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16697 "%s: sme_SetGTKOffload successfull", __func__);
16698 }
16699 else
16700 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016701 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16702 "%s: wlan not suspended GTKOffload request is stored",
16703 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016704 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016705
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016706 /* Need to clear any trace of key value in the memory.
16707 * Thus zero out the memory even though it is local
16708 * variable.
16709 */
16710 vos_mem_zero(&hddGtkOffloadReqParams,
16711 sizeof(hddGtkOffloadReqParams));
16712
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016713 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016714 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016715}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016716
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016717int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
16718 struct cfg80211_gtk_rekey_data *data)
16719{
16720 int ret;
16721
16722 vos_ssr_protect(__func__);
16723 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
16724 vos_ssr_unprotect(__func__);
16725
16726 return ret;
16727}
16728#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016729/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016730 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016731 * This function is used to set access control policy
16732 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016733static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
16734 struct net_device *dev,
16735 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016736{
16737 int i;
16738 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16739 hdd_hostapd_state_t *pHostapdState;
16740 tsap_Config_t *pConfig;
16741 v_CONTEXT_t pVosContext = NULL;
16742 hdd_context_t *pHddCtx;
16743 int status;
16744
16745 ENTER();
16746
16747 if (NULL == pAdapter)
16748 {
16749 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16750 "%s: HDD adapter is Null", __func__);
16751 return -ENODEV;
16752 }
16753
16754 if (NULL == params)
16755 {
16756 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16757 "%s: params is Null", __func__);
16758 return -EINVAL;
16759 }
16760
16761 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16762 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016763 if (0 != status)
16764 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016765 return status;
16766 }
16767
16768 pVosContext = pHddCtx->pvosContext;
16769 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
16770
16771 if (NULL == pHostapdState)
16772 {
16773 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16774 "%s: pHostapdState is Null", __func__);
16775 return -EINVAL;
16776 }
16777
16778 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
16779 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016780 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16781 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
16782 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016783
16784 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
16785 {
16786 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
16787
16788 /* default value */
16789 pConfig->num_accept_mac = 0;
16790 pConfig->num_deny_mac = 0;
16791
16792 /**
16793 * access control policy
16794 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
16795 * listed in hostapd.deny file.
16796 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
16797 * listed in hostapd.accept file.
16798 */
16799 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
16800 {
16801 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
16802 }
16803 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
16804 {
16805 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
16806 }
16807 else
16808 {
16809 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16810 "%s:Acl Policy : %d is not supported",
16811 __func__, params->acl_policy);
16812 return -ENOTSUPP;
16813 }
16814
16815 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
16816 {
16817 pConfig->num_accept_mac = params->n_acl_entries;
16818 for (i = 0; i < params->n_acl_entries; i++)
16819 {
16820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16821 "** Add ACL MAC entry %i in WhiletList :"
16822 MAC_ADDRESS_STR, i,
16823 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
16824
16825 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
16826 sizeof(qcmacaddr));
16827 }
16828 }
16829 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
16830 {
16831 pConfig->num_deny_mac = params->n_acl_entries;
16832 for (i = 0; i < params->n_acl_entries; i++)
16833 {
16834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16835 "** Add ACL MAC entry %i in BlackList :"
16836 MAC_ADDRESS_STR, i,
16837 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
16838
16839 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
16840 sizeof(qcmacaddr));
16841 }
16842 }
16843
16844 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
16845 {
16846 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16847 "%s: SAP Set Mac Acl fail", __func__);
16848 return -EINVAL;
16849 }
16850 }
16851 else
16852 {
16853 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016854 "%s: Invalid device_mode = %s (%d)",
16855 __func__, hdd_device_modetoString(pAdapter->device_mode),
16856 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016857 return -EINVAL;
16858 }
16859
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016860 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016861 return 0;
16862}
16863
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016864static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
16865 struct net_device *dev,
16866 const struct cfg80211_acl_data *params)
16867{
16868 int ret;
16869 vos_ssr_protect(__func__);
16870 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
16871 vos_ssr_unprotect(__func__);
16872
16873 return ret;
16874}
16875
Leo Chang9056f462013-08-01 19:21:11 -070016876#ifdef WLAN_NL80211_TESTMODE
16877#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070016878void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070016879(
16880 void *pAdapter,
16881 void *indCont
16882)
16883{
Leo Changd9df8aa2013-09-26 13:32:26 -070016884 tSirLPHBInd *lphbInd;
16885 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053016886 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070016887
16888 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016889 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070016890
c_hpothu73f35e62014-04-18 13:40:08 +053016891 if (pAdapter == NULL)
16892 {
16893 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16894 "%s: pAdapter is NULL\n",__func__);
16895 return;
16896 }
16897
Leo Chang9056f462013-08-01 19:21:11 -070016898 if (NULL == indCont)
16899 {
16900 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016901 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070016902 return;
16903 }
16904
c_hpothu73f35e62014-04-18 13:40:08 +053016905 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070016906 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070016907 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053016908 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070016909 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070016910 GFP_ATOMIC);
16911 if (!skb)
16912 {
16913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16914 "LPHB timeout, NL buffer alloc fail");
16915 return;
16916 }
16917
Leo Changac3ba772013-10-07 09:47:04 -070016918 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070016919 {
16920 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16921 "WLAN_HDD_TM_ATTR_CMD put fail");
16922 goto nla_put_failure;
16923 }
Leo Changac3ba772013-10-07 09:47:04 -070016924 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070016925 {
16926 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16927 "WLAN_HDD_TM_ATTR_TYPE put fail");
16928 goto nla_put_failure;
16929 }
Leo Changac3ba772013-10-07 09:47:04 -070016930 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070016931 sizeof(tSirLPHBInd), lphbInd))
16932 {
16933 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16934 "WLAN_HDD_TM_ATTR_DATA put fail");
16935 goto nla_put_failure;
16936 }
Leo Chang9056f462013-08-01 19:21:11 -070016937 cfg80211_testmode_event(skb, GFP_ATOMIC);
16938 return;
16939
16940nla_put_failure:
16941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16942 "NLA Put fail");
16943 kfree_skb(skb);
16944
16945 return;
16946}
16947#endif /* FEATURE_WLAN_LPHB */
16948
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016949static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070016950{
16951 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
16952 int err = 0;
16953#ifdef FEATURE_WLAN_LPHB
16954 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070016955 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016956
16957 ENTER();
16958
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016959 err = wlan_hdd_validate_context(pHddCtx);
16960 if (0 != err)
16961 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016962 return err;
16963 }
Leo Chang9056f462013-08-01 19:21:11 -070016964#endif /* FEATURE_WLAN_LPHB */
16965
16966 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
16967 if (err)
16968 {
16969 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16970 "%s Testmode INV ATTR", __func__);
16971 return err;
16972 }
16973
16974 if (!tb[WLAN_HDD_TM_ATTR_CMD])
16975 {
16976 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16977 "%s Testmode INV CMD", __func__);
16978 return -EINVAL;
16979 }
16980
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016981 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16982 TRACE_CODE_HDD_CFG80211_TESTMODE,
16983 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070016984 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
16985 {
16986#ifdef FEATURE_WLAN_LPHB
16987 /* Low Power Heartbeat configuration request */
16988 case WLAN_HDD_TM_CMD_WLAN_HB:
16989 {
16990 int buf_len;
16991 void *buf;
16992 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080016993 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070016994
16995 if (!tb[WLAN_HDD_TM_ATTR_DATA])
16996 {
16997 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16998 "%s Testmode INV DATA", __func__);
16999 return -EINVAL;
17000 }
17001
17002 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
17003 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080017004
17005 hb_params_temp =(tSirLPHBReq *)buf;
17006 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
17007 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
17008 return -EINVAL;
17009
Leo Chang9056f462013-08-01 19:21:11 -070017010 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
17011 if (NULL == hb_params)
17012 {
17013 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17014 "%s Request Buffer Alloc Fail", __func__);
17015 return -EINVAL;
17016 }
17017
17018 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070017019 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
17020 hb_params,
17021 wlan_hdd_cfg80211_lphb_ind_handler);
17022 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070017023 {
Leo Changd9df8aa2013-09-26 13:32:26 -070017024 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17025 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070017026 vos_mem_free(hb_params);
17027 }
Leo Chang9056f462013-08-01 19:21:11 -070017028 return 0;
17029 }
17030#endif /* FEATURE_WLAN_LPHB */
17031 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053017032 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
17033 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070017034 return -EOPNOTSUPP;
17035 }
17036
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017037 EXIT();
17038 return err;
Leo Chang9056f462013-08-01 19:21:11 -070017039}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017040
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053017041static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
17042#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
17043 struct wireless_dev *wdev,
17044#endif
17045 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017046{
17047 int ret;
17048
17049 vos_ssr_protect(__func__);
17050 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
17051 vos_ssr_unprotect(__func__);
17052
17053 return ret;
17054}
Leo Chang9056f462013-08-01 19:21:11 -070017055#endif /* CONFIG_NL80211_TESTMODE */
17056
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017057static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017058 struct net_device *dev,
17059 int idx, struct survey_info *survey)
17060{
17061 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
17062 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053017063 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017064 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053017065 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017066 v_S7_t snr,rssi;
17067 int status, i, j, filled = 0;
17068
17069 ENTER();
17070
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017071 if (NULL == pAdapter)
17072 {
17073 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17074 "%s: HDD adapter is Null", __func__);
17075 return -ENODEV;
17076 }
17077
17078 if (NULL == wiphy)
17079 {
17080 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
17081 "%s: wiphy is Null", __func__);
17082 return -ENODEV;
17083 }
17084
17085 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
17086 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017087 if (0 != status)
17088 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017089 return status;
17090 }
17091
Mihir Sheted9072e02013-08-21 17:02:29 +053017092 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
17093
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017094 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053017095 0 != pAdapter->survey_idx ||
17096 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017097 {
17098 /* The survey dump ops when implemented completely is expected to
17099 * return a survey of all channels and the ops is called by the
17100 * kernel with incremental values of the argument 'idx' till it
17101 * returns -ENONET. But we can only support the survey for the
17102 * operating channel for now. survey_idx is used to track
17103 * that the ops is called only once and then return -ENONET for
17104 * the next iteration
17105 */
17106 pAdapter->survey_idx = 0;
17107 return -ENONET;
17108 }
17109
Mukul Sharma9d5233b2015-06-11 20:28:20 +053017110 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
17111 {
17112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17113 "%s: Roaming in progress, hence return ", __func__);
17114 return -ENONET;
17115 }
17116
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017117 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
17118
17119 wlan_hdd_get_snr(pAdapter, &snr);
17120 wlan_hdd_get_rssi(pAdapter, &rssi);
17121
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017122 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17123 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
17124 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017125 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
17126 hdd_wlan_get_freq(channel, &freq);
17127
17128
17129 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
17130 {
17131 if (NULL == wiphy->bands[i])
17132 {
17133 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
17134 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
17135 continue;
17136 }
17137
17138 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
17139 {
17140 struct ieee80211_supported_band *band = wiphy->bands[i];
17141
17142 if (band->channels[j].center_freq == (v_U16_t)freq)
17143 {
17144 survey->channel = &band->channels[j];
17145 /* The Rx BDs contain SNR values in dB for the received frames
17146 * while the supplicant expects noise. So we calculate and
17147 * return the value of noise (dBm)
17148 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
17149 */
17150 survey->noise = rssi - snr;
17151 survey->filled = SURVEY_INFO_NOISE_DBM;
17152 filled = 1;
17153 }
17154 }
17155 }
17156
17157 if (filled)
17158 pAdapter->survey_idx = 1;
17159 else
17160 {
17161 pAdapter->survey_idx = 0;
17162 return -ENONET;
17163 }
17164
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017165 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017166 return 0;
17167}
17168
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053017169static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
17170 struct net_device *dev,
17171 int idx, struct survey_info *survey)
17172{
17173 int ret;
17174
17175 vos_ssr_protect(__func__);
17176 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
17177 vos_ssr_unprotect(__func__);
17178
17179 return ret;
17180}
17181
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017182/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017183 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017184 * this is called when cfg80211 driver resume
17185 * driver updates latest sched_scan scan result(if any) to cfg80211 database
17186 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017187int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017188{
17189 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
17190 hdd_adapter_t *pAdapter;
17191 hdd_adapter_list_node_t *pAdapterNode, *pNext;
17192 VOS_STATUS status = VOS_STATUS_SUCCESS;
17193
17194 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017195
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053017196 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017197 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017198 return 0;
17199 }
17200
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017201 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
17202 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017203 spin_lock(&pHddCtx->schedScan_lock);
17204 pHddCtx->isWiphySuspended = FALSE;
17205 if (TRUE != pHddCtx->isSchedScanUpdatePending)
17206 {
17207 spin_unlock(&pHddCtx->schedScan_lock);
17208 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17209 "%s: Return resume is not due to PNO indication", __func__);
17210 return 0;
17211 }
17212 // Reset flag to avoid updatating cfg80211 data old results again
17213 pHddCtx->isSchedScanUpdatePending = FALSE;
17214 spin_unlock(&pHddCtx->schedScan_lock);
17215
17216 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
17217
17218 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
17219 {
17220 pAdapter = pAdapterNode->pAdapter;
17221 if ( (NULL != pAdapter) &&
17222 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
17223 {
17224 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017225 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017226 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
17227 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017228 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017229 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017230 {
17231 /* Acquire wakelock to handle the case where APP's tries to
17232 * suspend immediately after updating the scan results. Whis
17233 * results in app's is in suspended state and not able to
17234 * process the connect request to AP
17235 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053017236 hdd_prevent_suspend_timeout(2000,
17237 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017238 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053017239 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017240
17241 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17242 "%s : cfg80211 scan result database updated", __func__);
17243
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017244 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017245 return 0;
17246
17247 }
17248 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
17249 pAdapterNode = pNext;
17250 }
17251
17252 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
17253 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017254 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017255 return 0;
17256}
17257
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017258int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
17259{
17260 int ret;
17261
17262 vos_ssr_protect(__func__);
17263 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
17264 vos_ssr_unprotect(__func__);
17265
17266 return ret;
17267}
17268
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017269/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017270 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017271 * this is called when cfg80211 driver suspends
17272 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017273int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017274 struct cfg80211_wowlan *wow)
17275{
17276 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017277 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017278
17279 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053017280
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017281 ret = wlan_hdd_validate_context(pHddCtx);
17282 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017283 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017284 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017285 }
17286
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053017287
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053017288 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
17289 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
17290 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017291 pHddCtx->isWiphySuspended = TRUE;
17292
17293 EXIT();
17294
17295 return 0;
17296}
17297
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053017298int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
17299 struct cfg80211_wowlan *wow)
17300{
17301 int ret;
17302
17303 vos_ssr_protect(__func__);
17304 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
17305 vos_ssr_unprotect(__func__);
17306
17307 return ret;
17308}
Jeff Johnson295189b2012-06-20 16:38:30 -070017309/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053017310static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070017311{
17312 .add_virtual_intf = wlan_hdd_add_virtual_intf,
17313 .del_virtual_intf = wlan_hdd_del_virtual_intf,
17314 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
17315 .change_station = wlan_hdd_change_station,
17316#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
17317 .add_beacon = wlan_hdd_cfg80211_add_beacon,
17318 .del_beacon = wlan_hdd_cfg80211_del_beacon,
17319 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017320#else
17321 .start_ap = wlan_hdd_cfg80211_start_ap,
17322 .change_beacon = wlan_hdd_cfg80211_change_beacon,
17323 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070017324#endif
17325 .change_bss = wlan_hdd_cfg80211_change_bss,
17326 .add_key = wlan_hdd_cfg80211_add_key,
17327 .get_key = wlan_hdd_cfg80211_get_key,
17328 .del_key = wlan_hdd_cfg80211_del_key,
17329 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080017330#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070017331 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080017332#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017333 .scan = wlan_hdd_cfg80211_scan,
17334 .connect = wlan_hdd_cfg80211_connect,
17335 .disconnect = wlan_hdd_cfg80211_disconnect,
17336 .join_ibss = wlan_hdd_cfg80211_join_ibss,
17337 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
17338 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
17339 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
17340 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070017341 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
17342 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053017343 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070017344#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17345 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
17346 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
17347 .set_txq_params = wlan_hdd_set_txq_params,
17348#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017349 .get_station = wlan_hdd_cfg80211_get_station,
17350 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
17351 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017352 .add_station = wlan_hdd_cfg80211_add_station,
17353#ifdef FEATURE_WLAN_LFR
17354 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
17355 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
17356 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
17357#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017358#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
17359 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
17360#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017361#ifdef FEATURE_WLAN_TDLS
17362 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
17363 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
17364#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017365#ifdef WLAN_FEATURE_GTK_OFFLOAD
17366 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
17367#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017368#ifdef FEATURE_WLAN_SCAN_PNO
17369 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
17370 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
17371#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017372 .resume = wlan_hdd_cfg80211_resume_wlan,
17373 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017374 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070017375#ifdef WLAN_NL80211_TESTMODE
17376 .testmode_cmd = wlan_hdd_cfg80211_testmode,
17377#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017378 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070017379};
17380