blob: 704ea8b82e05d8bfde634e6192017975a8748ea3 [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070098
99#define g_mode_rates_size (12)
100#define a_mode_rates_size (8)
101#define FREQ_BASE_80211G (2407)
102#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700103#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530104#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700105#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800106 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700107
108#define HDD2GHZCHAN(freq, chan, flag) { \
109 .band = IEEE80211_BAND_2GHZ, \
110 .center_freq = (freq), \
111 .hw_value = (chan),\
112 .flags = (flag), \
113 .max_antenna_gain = 0 ,\
114 .max_power = 30, \
115}
116
117#define HDD5GHZCHAN(freq, chan, flag) { \
118 .band = IEEE80211_BAND_5GHZ, \
119 .center_freq = (freq), \
120 .hw_value = (chan),\
121 .flags = (flag), \
122 .max_antenna_gain = 0 ,\
123 .max_power = 30, \
124}
125
126#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
127{\
128 .bitrate = rate, \
129 .hw_value = rate_id, \
130 .flags = flag, \
131}
132
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530133#ifdef WLAN_FEATURE_VOWIFI_11R
134#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
135#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
136#endif
137
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530138#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530139#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530140
Sunil Duttc69bccb2014-05-26 21:30:20 +0530141#ifdef WLAN_FEATURE_LINK_LAYER_STATS
142/*
143 * Used to allocate the size of 4096 for the link layer stats.
144 * The size of 4096 is considered assuming that all data per
145 * respective event fit with in the limit.Please take a call
146 * on the limit based on the data requirements on link layer
147 * statistics.
148 */
149#define LL_STATS_EVENT_BUF_SIZE 4096
150#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530151#ifdef WLAN_FEATURE_EXTSCAN
152/*
153 * Used to allocate the size of 4096 for the EXTScan NL data.
154 * The size of 4096 is considered assuming that all data per
155 * respective event fit with in the limit.Please take a call
156 * on the limit based on the data requirements.
157 */
158
159#define EXTSCAN_EVENT_BUF_SIZE 4096
160#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
161#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530162
Atul Mittal115287b2014-07-08 13:26:33 +0530163/*EXT TDLS*/
164/*
165 * Used to allocate the size of 4096 for the TDLS.
166 * The size of 4096 is considered assuming that all data per
167 * respective event fit with in the limit.Please take a call
168 * on the limit based on the data requirements on link layer
169 * statistics.
170 */
171#define EXTTDLS_EVENT_BUF_SIZE 4096
172
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530173static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700174{
175 WLAN_CIPHER_SUITE_WEP40,
176 WLAN_CIPHER_SUITE_WEP104,
177 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800178#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700179#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
180 WLAN_CIPHER_SUITE_KRK,
181 WLAN_CIPHER_SUITE_CCMP,
182#else
183 WLAN_CIPHER_SUITE_CCMP,
184#endif
185#ifdef FEATURE_WLAN_WAPI
186 WLAN_CIPHER_SUITE_SMS4,
187#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700188#ifdef WLAN_FEATURE_11W
189 WLAN_CIPHER_SUITE_AES_CMAC,
190#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700191};
192
193static inline int is_broadcast_ether_addr(const u8 *addr)
194{
195 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
196 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
197}
198
199static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530200{
Jeff Johnson295189b2012-06-20 16:38:30 -0700201 HDD2GHZCHAN(2412, 1, 0) ,
202 HDD2GHZCHAN(2417, 2, 0) ,
203 HDD2GHZCHAN(2422, 3, 0) ,
204 HDD2GHZCHAN(2427, 4, 0) ,
205 HDD2GHZCHAN(2432, 5, 0) ,
206 HDD2GHZCHAN(2437, 6, 0) ,
207 HDD2GHZCHAN(2442, 7, 0) ,
208 HDD2GHZCHAN(2447, 8, 0) ,
209 HDD2GHZCHAN(2452, 9, 0) ,
210 HDD2GHZCHAN(2457, 10, 0) ,
211 HDD2GHZCHAN(2462, 11, 0) ,
212 HDD2GHZCHAN(2467, 12, 0) ,
213 HDD2GHZCHAN(2472, 13, 0) ,
214 HDD2GHZCHAN(2484, 14, 0) ,
215};
216
Jeff Johnson295189b2012-06-20 16:38:30 -0700217static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
218{
219 HDD2GHZCHAN(2412, 1, 0) ,
220 HDD2GHZCHAN(2437, 6, 0) ,
221 HDD2GHZCHAN(2462, 11, 0) ,
222};
Jeff Johnson295189b2012-06-20 16:38:30 -0700223
224static struct ieee80211_channel hdd_channels_5_GHZ[] =
225{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700226 HDD5GHZCHAN(4920, 240, 0) ,
227 HDD5GHZCHAN(4940, 244, 0) ,
228 HDD5GHZCHAN(4960, 248, 0) ,
229 HDD5GHZCHAN(4980, 252, 0) ,
230 HDD5GHZCHAN(5040, 208, 0) ,
231 HDD5GHZCHAN(5060, 212, 0) ,
232 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700233 HDD5GHZCHAN(5180, 36, 0) ,
234 HDD5GHZCHAN(5200, 40, 0) ,
235 HDD5GHZCHAN(5220, 44, 0) ,
236 HDD5GHZCHAN(5240, 48, 0) ,
237 HDD5GHZCHAN(5260, 52, 0) ,
238 HDD5GHZCHAN(5280, 56, 0) ,
239 HDD5GHZCHAN(5300, 60, 0) ,
240 HDD5GHZCHAN(5320, 64, 0) ,
241 HDD5GHZCHAN(5500,100, 0) ,
242 HDD5GHZCHAN(5520,104, 0) ,
243 HDD5GHZCHAN(5540,108, 0) ,
244 HDD5GHZCHAN(5560,112, 0) ,
245 HDD5GHZCHAN(5580,116, 0) ,
246 HDD5GHZCHAN(5600,120, 0) ,
247 HDD5GHZCHAN(5620,124, 0) ,
248 HDD5GHZCHAN(5640,128, 0) ,
249 HDD5GHZCHAN(5660,132, 0) ,
250 HDD5GHZCHAN(5680,136, 0) ,
251 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800252#ifdef FEATURE_WLAN_CH144
253 HDD5GHZCHAN(5720,144, 0) ,
254#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700255 HDD5GHZCHAN(5745,149, 0) ,
256 HDD5GHZCHAN(5765,153, 0) ,
257 HDD5GHZCHAN(5785,157, 0) ,
258 HDD5GHZCHAN(5805,161, 0) ,
259 HDD5GHZCHAN(5825,165, 0) ,
260};
261
262static struct ieee80211_rate g_mode_rates[] =
263{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530264 HDD_G_MODE_RATETAB(10, 0x1, 0),
265 HDD_G_MODE_RATETAB(20, 0x2, 0),
266 HDD_G_MODE_RATETAB(55, 0x4, 0),
267 HDD_G_MODE_RATETAB(110, 0x8, 0),
268 HDD_G_MODE_RATETAB(60, 0x10, 0),
269 HDD_G_MODE_RATETAB(90, 0x20, 0),
270 HDD_G_MODE_RATETAB(120, 0x40, 0),
271 HDD_G_MODE_RATETAB(180, 0x80, 0),
272 HDD_G_MODE_RATETAB(240, 0x100, 0),
273 HDD_G_MODE_RATETAB(360, 0x200, 0),
274 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700275 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530276};
Jeff Johnson295189b2012-06-20 16:38:30 -0700277
278static struct ieee80211_rate a_mode_rates[] =
279{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530280 HDD_G_MODE_RATETAB(60, 0x10, 0),
281 HDD_G_MODE_RATETAB(90, 0x20, 0),
282 HDD_G_MODE_RATETAB(120, 0x40, 0),
283 HDD_G_MODE_RATETAB(180, 0x80, 0),
284 HDD_G_MODE_RATETAB(240, 0x100, 0),
285 HDD_G_MODE_RATETAB(360, 0x200, 0),
286 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700287 HDD_G_MODE_RATETAB(540, 0x800, 0),
288};
289
290static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
291{
292 .channels = hdd_channels_2_4_GHZ,
293 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
294 .band = IEEE80211_BAND_2GHZ,
295 .bitrates = g_mode_rates,
296 .n_bitrates = g_mode_rates_size,
297 .ht_cap.ht_supported = 1,
298 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
299 | IEEE80211_HT_CAP_GRN_FLD
300 | IEEE80211_HT_CAP_DSSSCCK40
301 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
302 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
303 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
304 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
305 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
306 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
307};
308
Jeff Johnson295189b2012-06-20 16:38:30 -0700309static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
310{
311 .channels = hdd_social_channels_2_4_GHZ,
312 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
313 .band = IEEE80211_BAND_2GHZ,
314 .bitrates = g_mode_rates,
315 .n_bitrates = g_mode_rates_size,
316 .ht_cap.ht_supported = 1,
317 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
318 | IEEE80211_HT_CAP_GRN_FLD
319 | IEEE80211_HT_CAP_DSSSCCK40
320 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
321 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
322 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
323 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
324 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
325 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
326};
Jeff Johnson295189b2012-06-20 16:38:30 -0700327
328static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
329{
330 .channels = hdd_channels_5_GHZ,
331 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
332 .band = IEEE80211_BAND_5GHZ,
333 .bitrates = a_mode_rates,
334 .n_bitrates = a_mode_rates_size,
335 .ht_cap.ht_supported = 1,
336 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
337 | IEEE80211_HT_CAP_GRN_FLD
338 | IEEE80211_HT_CAP_DSSSCCK40
339 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
340 | IEEE80211_HT_CAP_SGI_40
341 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
342 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
343 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
344 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
345 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
346 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
347};
348
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530349/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700350 TX/RX direction for each kind of interface */
351static const struct ieee80211_txrx_stypes
352wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
353 [NL80211_IFTYPE_STATION] = {
354 .tx = 0xffff,
355 .rx = BIT(SIR_MAC_MGMT_ACTION) |
356 BIT(SIR_MAC_MGMT_PROBE_REQ),
357 },
358 [NL80211_IFTYPE_AP] = {
359 .tx = 0xffff,
360 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
361 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
362 BIT(SIR_MAC_MGMT_PROBE_REQ) |
363 BIT(SIR_MAC_MGMT_DISASSOC) |
364 BIT(SIR_MAC_MGMT_AUTH) |
365 BIT(SIR_MAC_MGMT_DEAUTH) |
366 BIT(SIR_MAC_MGMT_ACTION),
367 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700368 [NL80211_IFTYPE_ADHOC] = {
369 .tx = 0xffff,
370 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
371 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
372 BIT(SIR_MAC_MGMT_PROBE_REQ) |
373 BIT(SIR_MAC_MGMT_DISASSOC) |
374 BIT(SIR_MAC_MGMT_AUTH) |
375 BIT(SIR_MAC_MGMT_DEAUTH) |
376 BIT(SIR_MAC_MGMT_ACTION),
377 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700378 [NL80211_IFTYPE_P2P_CLIENT] = {
379 .tx = 0xffff,
380 .rx = BIT(SIR_MAC_MGMT_ACTION) |
381 BIT(SIR_MAC_MGMT_PROBE_REQ),
382 },
383 [NL80211_IFTYPE_P2P_GO] = {
384 /* This is also same as for SoftAP */
385 .tx = 0xffff,
386 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
387 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
388 BIT(SIR_MAC_MGMT_PROBE_REQ) |
389 BIT(SIR_MAC_MGMT_DISASSOC) |
390 BIT(SIR_MAC_MGMT_AUTH) |
391 BIT(SIR_MAC_MGMT_DEAUTH) |
392 BIT(SIR_MAC_MGMT_ACTION),
393 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700394};
395
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800396#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800397static const struct ieee80211_iface_limit
398wlan_hdd_iface_limit[] = {
399 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800400 /* max = 3 ; Our driver create two interfaces during driver init
401 * wlan0 and p2p0 interfaces. p2p0 is considered as station
402 * interface until a group is formed. In JB architecture, once the
403 * group is formed, interface type of p2p0 is changed to P2P GO or
404 * Client.
405 * When supplicant remove the group, it first issue a set interface
406 * cmd to change the mode back to Station. In JB this works fine as
407 * we advertize two station type interface during driver init.
408 * Some vendors create separate interface for P2P GO/Client,
409 * after group formation(Third one). But while group remove
410 * supplicant first tries to change the mode(3rd interface) to STATION
411 * But as we advertized only two sta type interfaces nl80211 was
412 * returning error for the third one which was leading to failure in
413 * delete interface. Ideally while removing the group, supplicant
414 * should not try to change the 3rd interface mode to Station type.
415 * Till we get a fix in wpa_supplicant, we advertize max STA
416 * interface type to 3
417 */
418 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800419 .types = BIT(NL80211_IFTYPE_STATION),
420 },
421 {
422 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700423 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800424 },
425 {
426 .max = 1,
427 .types = BIT(NL80211_IFTYPE_P2P_GO) |
428 BIT(NL80211_IFTYPE_P2P_CLIENT),
429 },
430};
431
432/* By default, only single channel concurrency is allowed */
433static struct ieee80211_iface_combination
434wlan_hdd_iface_combination = {
435 .limits = wlan_hdd_iface_limit,
436 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800437 /*
438 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
439 * and p2p0 interfaces during driver init
440 * Some vendors create separate interface for P2P operations.
441 * wlan0: STA interface
442 * p2p0: P2P Device interface, action frames goes
443 * through this interface.
444 * p2p-xx: P2P interface, After GO negotiation this interface is
445 * created for p2p operations(GO/CLIENT interface).
446 */
447 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800448 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
449 .beacon_int_infra_match = false,
450};
451#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800452
Jeff Johnson295189b2012-06-20 16:38:30 -0700453static struct cfg80211_ops wlan_hdd_cfg80211_ops;
454
455/* Data rate 100KBPS based on IE Index */
456struct index_data_rate_type
457{
458 v_U8_t beacon_rate_index;
459 v_U16_t supported_rate[4];
460};
461
462/* 11B, 11G Rate table include Basic rate and Extended rate
463 The IDX field is the rate index
464 The HI field is the rate when RSSI is strong or being ignored
465 (in this case we report actual rate)
466 The MID field is the rate when RSSI is moderate
467 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
468 The LO field is the rate when RSSI is low
469 (in this case we don't report rates, actual current rate used)
470 */
471static const struct
472{
473 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700474 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700475} supported_data_rate[] =
476{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700477/* IDX HI HM LM LO (RSSI-based index */
478 {2, { 10, 10, 10, 0}},
479 {4, { 20, 20, 10, 0}},
480 {11, { 55, 20, 10, 0}},
481 {12, { 60, 55, 20, 0}},
482 {18, { 90, 55, 20, 0}},
483 {22, {110, 55, 20, 0}},
484 {24, {120, 90, 60, 0}},
485 {36, {180, 120, 60, 0}},
486 {44, {220, 180, 60, 0}},
487 {48, {240, 180, 90, 0}},
488 {66, {330, 180, 90, 0}},
489 {72, {360, 240, 90, 0}},
490 {96, {480, 240, 120, 0}},
491 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700492};
493
494/* MCS Based rate table */
495static struct index_data_rate_type supported_mcs_rate[] =
496{
497/* MCS L20 L40 S20 S40 */
498 {0, {65, 135, 72, 150}},
499 {1, {130, 270, 144, 300}},
500 {2, {195, 405, 217, 450}},
501 {3, {260, 540, 289, 600}},
502 {4, {390, 810, 433, 900}},
503 {5, {520, 1080, 578, 1200}},
504 {6, {585, 1215, 650, 1350}},
505 {7, {650, 1350, 722, 1500}}
506};
507
Leo Chang6f8870f2013-03-26 18:11:36 -0700508#ifdef WLAN_FEATURE_11AC
509
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530510#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700511
512struct index_vht_data_rate_type
513{
514 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530515 v_U16_t supported_VHT80_rate[2];
516 v_U16_t supported_VHT40_rate[2];
517 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700518};
519
520typedef enum
521{
522 DATA_RATE_11AC_MAX_MCS_7,
523 DATA_RATE_11AC_MAX_MCS_8,
524 DATA_RATE_11AC_MAX_MCS_9,
525 DATA_RATE_11AC_MAX_MCS_NA
526} eDataRate11ACMaxMcs;
527
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530528/* SSID broadcast type */
529typedef enum eSSIDBcastType
530{
531 eBCAST_UNKNOWN = 0,
532 eBCAST_NORMAL = 1,
533 eBCAST_HIDDEN = 2,
534} tSSIDBcastType;
535
Leo Chang6f8870f2013-03-26 18:11:36 -0700536/* MCS Based VHT rate table */
537static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
538{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530539/* MCS L80 S80 L40 S40 L20 S40*/
540 {0, {293, 325}, {135, 150}, {65, 72}},
541 {1, {585, 650}, {270, 300}, {130, 144}},
542 {2, {878, 975}, {405, 450}, {195, 217}},
543 {3, {1170, 1300}, {540, 600}, {260, 289}},
544 {4, {1755, 1950}, {810, 900}, {390, 433}},
545 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
546 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
547 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
548 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
549 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700550};
551#endif /* WLAN_FEATURE_11AC */
552
c_hpothu79aab322014-07-14 21:11:01 +0530553/*array index points to MCS and array value points respective rssi*/
554static int rssiMcsTbl[][10] =
555{
556/*MCS 0 1 2 3 4 5 6 7 8 9*/
557 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
558 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
559 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
560};
561
Jeff Johnson295189b2012-06-20 16:38:30 -0700562extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530563#ifdef FEATURE_WLAN_SCAN_PNO
564static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
565#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700566
Leo Chang9056f462013-08-01 19:21:11 -0700567#ifdef WLAN_NL80211_TESTMODE
568enum wlan_hdd_tm_attr
569{
570 WLAN_HDD_TM_ATTR_INVALID = 0,
571 WLAN_HDD_TM_ATTR_CMD = 1,
572 WLAN_HDD_TM_ATTR_DATA = 2,
573 WLAN_HDD_TM_ATTR_TYPE = 3,
574 /* keep last */
575 WLAN_HDD_TM_ATTR_AFTER_LAST,
576 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
577};
578
579enum wlan_hdd_tm_cmd
580{
581 WLAN_HDD_TM_CMD_WLAN_HB = 1,
582};
583
584#define WLAN_HDD_TM_DATA_MAX_LEN 5000
585
586static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
587{
588 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
589 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
590 .len = WLAN_HDD_TM_DATA_MAX_LEN },
591};
592#endif /* WLAN_NL80211_TESTMODE */
593
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800594#ifdef FEATURE_WLAN_CH_AVOID
595/*
596 * FUNCTION: wlan_hdd_send_avoid_freq_event
597 * This is called when wlan driver needs to send vendor specific
598 * avoid frequency range event to userspace
599 */
600int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
601 tHddAvoidFreqList *pAvoidFreqList)
602{
603 struct sk_buff *vendor_event;
604
605 ENTER();
606
607 if (!pHddCtx)
608 {
609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
610 "%s: HDD context is null", __func__);
611 return -1;
612 }
613
614 if (!pAvoidFreqList)
615 {
616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
617 "%s: pAvoidFreqList is null", __func__);
618 return -1;
619 }
620
621 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530622#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
623 NULL,
624#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800625 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530626 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800627 GFP_KERNEL);
628 if (!vendor_event)
629 {
630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
631 "%s: cfg80211_vendor_event_alloc failed", __func__);
632 return -1;
633 }
634
635 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
636 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
637
638 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
639
640 EXIT();
641 return 0;
642}
643#endif /* FEATURE_WLAN_CH_AVOID */
644
Srinivas Dasari030bad32015-02-18 23:23:54 +0530645/*
646 * FUNCTION: __wlan_hdd_cfg80211_nan_request
647 * This is called when wlan driver needs to send vendor specific
648 * nan request event.
649 */
650static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
651 struct wireless_dev *wdev,
652 const void *data, int data_len)
653{
654 tNanRequestReq nan_req;
655 VOS_STATUS status;
656 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530657 struct net_device *dev = wdev->netdev;
658 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
659 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530660 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
661
662 if (0 == data_len)
663 {
664 hddLog(VOS_TRACE_LEVEL_ERROR,
665 FL("NAN - Invalid Request, length = 0"));
666 return ret_val;
667 }
668
669 if (NULL == data)
670 {
671 hddLog(VOS_TRACE_LEVEL_ERROR,
672 FL("NAN - Invalid Request, data is NULL"));
673 return ret_val;
674 }
675
676 status = wlan_hdd_validate_context(pHddCtx);
677 if (0 != status)
678 {
679 hddLog(VOS_TRACE_LEVEL_ERROR,
680 FL("HDD context is not valid"));
681 return -EINVAL;
682 }
683
684 hddLog(LOG1, FL("Received NAN command"));
685 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
686 (tANI_U8 *)data, data_len);
687
688 /* check the NAN Capability */
689 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
690 {
691 hddLog(VOS_TRACE_LEVEL_ERROR,
692 FL("NAN is not supported by Firmware"));
693 return -EINVAL;
694 }
695
696 nan_req.request_data_len = data_len;
697 nan_req.request_data = data;
698
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530699 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530700 if (VOS_STATUS_SUCCESS == status)
701 {
702 ret_val = 0;
703 }
704 return ret_val;
705}
706
707/*
708 * FUNCTION: wlan_hdd_cfg80211_nan_request
709 * Wrapper to protect the nan vendor command from ssr
710 */
711static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
712 struct wireless_dev *wdev,
713 const void *data, int data_len)
714{
715 int ret;
716
717 vos_ssr_protect(__func__);
718 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
719 vos_ssr_unprotect(__func__);
720
721 return ret;
722}
723
724/*
725 * FUNCTION: wlan_hdd_cfg80211_nan_callback
726 * This is a callback function and it gets called
727 * when we need to report nan response event to
728 * upper layers.
729 */
730static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
731{
732 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
733 struct sk_buff *vendor_event;
734 int status;
735 tSirNanEvent *data;
736
737 ENTER();
738 if (NULL == msg)
739 {
740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
741 FL(" msg received here is null"));
742 return;
743 }
744 data = msg;
745
746 status = wlan_hdd_validate_context(pHddCtx);
747
748 if (0 != status)
749 {
750 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
751 FL("HDD context is not valid"));
752 return;
753 }
754
755 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530756#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
757 NULL,
758#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530759 data->event_data_len +
760 NLMSG_HDRLEN,
761 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
762 GFP_KERNEL);
763
764 if (!vendor_event)
765 {
766 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
767 FL("cfg80211_vendor_event_alloc failed"));
768 return;
769 }
770 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
771 data->event_data_len, data->event_data))
772 {
773 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
774 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
775 kfree_skb(vendor_event);
776 return;
777 }
778 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
779 EXIT();
780}
781
782/*
783 * FUNCTION: wlan_hdd_cfg80211_nan_init
784 * This function is called to register the callback to sme layer
785 */
786inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
787{
788 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
789}
790
791
Sunil Duttc69bccb2014-05-26 21:30:20 +0530792#ifdef WLAN_FEATURE_LINK_LAYER_STATS
793
794static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
795 struct sk_buff *vendor_event)
796{
797 if (nla_put_u8(vendor_event,
798 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
799 stats->rate.preamble) ||
800 nla_put_u8(vendor_event,
801 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
802 stats->rate.nss) ||
803 nla_put_u8(vendor_event,
804 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
805 stats->rate.bw) ||
806 nla_put_u8(vendor_event,
807 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
808 stats->rate.rateMcsIdx) ||
809 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
810 stats->rate.bitrate ) ||
811 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
812 stats->txMpdu ) ||
813 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
814 stats->rxMpdu ) ||
815 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
816 stats->mpduLost ) ||
817 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
818 stats->retries) ||
819 nla_put_u32(vendor_event,
820 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
821 stats->retriesShort ) ||
822 nla_put_u32(vendor_event,
823 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
824 stats->retriesLong))
825 {
826 hddLog(VOS_TRACE_LEVEL_ERROR,
827 FL("QCA_WLAN_VENDOR_ATTR put fail"));
828 return FALSE;
829 }
830 return TRUE;
831}
832
833static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
834 struct sk_buff *vendor_event)
835{
836 u32 i = 0;
837 struct nlattr *rateInfo;
838 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
839 stats->type) ||
840 nla_put(vendor_event,
841 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
842 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
843 nla_put_u32(vendor_event,
844 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
845 stats->capabilities) ||
846 nla_put_u32(vendor_event,
847 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
848 stats->numRate))
849 {
850 hddLog(VOS_TRACE_LEVEL_ERROR,
851 FL("QCA_WLAN_VENDOR_ATTR put fail"));
852 goto error;
853 }
854
855 rateInfo = nla_nest_start(vendor_event,
856 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530857 if(!rateInfo)
858 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530859 for (i = 0; i < stats->numRate; i++)
860 {
861 struct nlattr *rates;
862 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
863 stats->rateStats +
864 (i * sizeof(tSirWifiRateStat)));
865 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530866 if(!rates)
867 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530868
869 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
870 {
871 hddLog(VOS_TRACE_LEVEL_ERROR,
872 FL("QCA_WLAN_VENDOR_ATTR put fail"));
873 return FALSE;
874 }
875 nla_nest_end(vendor_event, rates);
876 }
877 nla_nest_end(vendor_event, rateInfo);
878
879 return TRUE;
880error:
881 return FALSE;
882}
883
884static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
885 struct sk_buff *vendor_event)
886{
887 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
888 stats->ac ) ||
889 nla_put_u32(vendor_event,
890 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
891 stats->txMpdu ) ||
892 nla_put_u32(vendor_event,
893 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
894 stats->rxMpdu ) ||
895 nla_put_u32(vendor_event,
896 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
897 stats->txMcast ) ||
898 nla_put_u32(vendor_event,
899 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
900 stats->rxMcast ) ||
901 nla_put_u32(vendor_event,
902 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
903 stats->rxAmpdu ) ||
904 nla_put_u32(vendor_event,
905 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
906 stats->txAmpdu ) ||
907 nla_put_u32(vendor_event,
908 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
909 stats->mpduLost )||
910 nla_put_u32(vendor_event,
911 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
912 stats->retries ) ||
913 nla_put_u32(vendor_event,
914 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
915 stats->retriesShort ) ||
916 nla_put_u32(vendor_event,
917 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
918 stats->retriesLong ) ||
919 nla_put_u32(vendor_event,
920 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
921 stats->contentionTimeMin ) ||
922 nla_put_u32(vendor_event,
923 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
924 stats->contentionTimeMax ) ||
925 nla_put_u32(vendor_event,
926 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
927 stats->contentionTimeAvg ) ||
928 nla_put_u32(vendor_event,
929 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
930 stats->contentionNumSamples ))
931 {
932 hddLog(VOS_TRACE_LEVEL_ERROR,
933 FL("QCA_WLAN_VENDOR_ATTR put fail") );
934 return FALSE;
935 }
936 return TRUE;
937}
938
939static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
940 struct sk_buff *vendor_event)
941{
Dino Myclec8f3f332014-07-21 16:48:27 +0530942 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530943 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
944 nla_put(vendor_event,
945 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
946 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
947 nla_put_u32(vendor_event,
948 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
949 stats->state ) ||
950 nla_put_u32(vendor_event,
951 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
952 stats->roaming ) ||
953 nla_put_u32(vendor_event,
954 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
955 stats->capabilities ) ||
956 nla_put(vendor_event,
957 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
958 strlen(stats->ssid), stats->ssid) ||
959 nla_put(vendor_event,
960 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
961 WNI_CFG_BSSID_LEN, stats->bssid) ||
962 nla_put(vendor_event,
963 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
964 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
965 nla_put(vendor_event,
966 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
967 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
968 )
969 {
970 hddLog(VOS_TRACE_LEVEL_ERROR,
971 FL("QCA_WLAN_VENDOR_ATTR put fail") );
972 return FALSE;
973 }
974 return TRUE;
975}
976
Dino Mycle3b9536d2014-07-09 22:05:24 +0530977static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
978 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530979 struct sk_buff *vendor_event)
980{
981 int i = 0;
982 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530983 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
984 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530985 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530986
Sunil Duttc69bccb2014-05-26 21:30:20 +0530987 if (FALSE == put_wifi_interface_info(
988 &pWifiIfaceStat->info,
989 vendor_event))
990 {
991 hddLog(VOS_TRACE_LEVEL_ERROR,
992 FL("QCA_WLAN_VENDOR_ATTR put fail") );
993 return FALSE;
994
995 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530996 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
997 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
998 if (NULL == pWifiIfaceStatTL)
999 {
1000 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
1001 return FALSE;
1002 }
1003
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301004 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
1005 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1006 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1007 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1008
1009 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1010 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1011 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1012 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301013
1014 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1015 {
1016 if (VOS_STATUS_SUCCESS ==
1017 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1018 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1019 {
1020 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1021 * obtained from TL structure
1022 */
1023
1024 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1025 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301026 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1027
Srinivas Dasari98947432014-11-07 19:41:24 +05301028 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1029 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1030 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1031 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1032 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1033 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1034 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1035 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301036
Srinivas Dasari98947432014-11-07 19:41:24 +05301037 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1038 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1039 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1040 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1041 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1042 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1043 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1044 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301045
Srinivas Dasari98947432014-11-07 19:41:24 +05301046 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1047 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1048 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1049 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1050 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1051 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1052 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1053 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301054 }
1055 else
1056 {
1057 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1058 }
1059
Dino Mycle3b9536d2014-07-09 22:05:24 +05301060 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1061 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1062 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1063 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1064 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1065 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1066 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1067 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1068 }
1069 else
1070 {
1071 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1072 }
1073
1074
Sunil Duttc69bccb2014-05-26 21:30:20 +05301075
1076 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301077 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1078 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_IFACE) ||
1079 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301080 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1081 pWifiIfaceStat->beaconRx) ||
1082 nla_put_u32(vendor_event,
1083 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1084 pWifiIfaceStat->mgmtRx) ||
1085 nla_put_u32(vendor_event,
1086 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1087 pWifiIfaceStat->mgmtActionRx) ||
1088 nla_put_u32(vendor_event,
1089 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1090 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301091 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301092 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1093 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301094 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301095 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1096 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301097 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301098 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1099 pWifiIfaceStat->rssiAck))
1100 {
1101 hddLog(VOS_TRACE_LEVEL_ERROR,
1102 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301103 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301104 return FALSE;
1105 }
1106
1107 wmmInfo = nla_nest_start(vendor_event,
1108 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301109 if(!wmmInfo)
1110 {
1111 vos_mem_free(pWifiIfaceStatTL);
1112 return FALSE;
1113 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301114 for (i = 0; i < WIFI_AC_MAX; i++)
1115 {
1116 struct nlattr *wmmStats;
1117 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301118 if(!wmmStats)
1119 {
1120 vos_mem_free(pWifiIfaceStatTL);
1121 return FALSE;
1122 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301123 if (FALSE == put_wifi_wmm_ac_stat(
1124 &pWifiIfaceStat->AccessclassStats[i],
1125 vendor_event))
1126 {
1127 hddLog(VOS_TRACE_LEVEL_ERROR,
1128 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301129 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301130 return FALSE;
1131 }
1132
1133 nla_nest_end(vendor_event, wmmStats);
1134 }
1135 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301136 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301137 return TRUE;
1138}
1139
1140static tSirWifiInterfaceMode
1141 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1142{
1143 switch (deviceMode)
1144 {
1145 case WLAN_HDD_INFRA_STATION:
1146 return WIFI_INTERFACE_STA;
1147 case WLAN_HDD_SOFTAP:
1148 return WIFI_INTERFACE_SOFTAP;
1149 case WLAN_HDD_P2P_CLIENT:
1150 return WIFI_INTERFACE_P2P_CLIENT;
1151 case WLAN_HDD_P2P_GO:
1152 return WIFI_INTERFACE_P2P_GO;
1153 case WLAN_HDD_IBSS:
1154 return WIFI_INTERFACE_IBSS;
1155 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301156 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301157 }
1158}
1159
1160static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1161 tpSirWifiInterfaceInfo pInfo)
1162{
1163 v_U8_t *staMac = NULL;
1164 hdd_station_ctx_t *pHddStaCtx;
1165 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1166 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1167
1168 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1169
1170 vos_mem_copy(pInfo->macAddr,
1171 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1172
1173 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1174 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1175 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1176 {
1177 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1178 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1179 {
1180 pInfo->state = WIFI_DISCONNECTED;
1181 }
1182 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1183 {
1184 hddLog(VOS_TRACE_LEVEL_ERROR,
1185 "%s: Session ID %d, Connection is in progress", __func__,
1186 pAdapter->sessionId);
1187 pInfo->state = WIFI_ASSOCIATING;
1188 }
1189 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1190 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1191 {
1192 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1193 hddLog(VOS_TRACE_LEVEL_ERROR,
1194 "%s: client " MAC_ADDRESS_STR
1195 " is in the middle of WPS/EAPOL exchange.", __func__,
1196 MAC_ADDR_ARRAY(staMac));
1197 pInfo->state = WIFI_AUTHENTICATING;
1198 }
1199 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1200 {
1201 pInfo->state = WIFI_ASSOCIATED;
1202 vos_mem_copy(pInfo->bssid,
1203 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1204 vos_mem_copy(pInfo->ssid,
1205 pHddStaCtx->conn_info.SSID.SSID.ssId,
1206 pHddStaCtx->conn_info.SSID.SSID.length);
1207 //NULL Terminate the string.
1208 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1209 }
1210 }
1211 vos_mem_copy(pInfo->countryStr,
1212 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1213
1214 vos_mem_copy(pInfo->apCountryStr,
1215 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1216
1217 return TRUE;
1218}
1219
1220/*
1221 * hdd_link_layer_process_peer_stats () - This function is called after
1222 * receiving Link Layer Peer statistics from FW.This function converts
1223 * the firmware data to the NL data and sends the same to the kernel/upper
1224 * layers.
1225 */
1226static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1227 v_VOID_t *pData)
1228{
1229 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1230 tpSirWifiRateStat pWifiRateStat;
1231 tpSirWifiPeerStat pWifiPeerStat;
1232 tpSirWifiPeerInfo pWifiPeerInfo;
1233 struct nlattr *peerInfo;
1234 struct sk_buff *vendor_event;
1235 int status, i;
1236
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301237 ENTER();
1238
Sunil Duttc69bccb2014-05-26 21:30:20 +05301239 status = wlan_hdd_validate_context(pHddCtx);
1240 if (0 != status)
1241 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301242 return;
1243 }
1244
1245 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1246
1247 hddLog(VOS_TRACE_LEVEL_INFO,
1248 "LL_STATS_PEER_ALL : numPeers %u",
1249 pWifiPeerStat->numPeers);
1250 {
1251 for (i = 0; i < pWifiPeerStat->numPeers; i++)
1252 {
1253 pWifiPeerInfo = (tpSirWifiPeerInfo)
1254 ((uint8 *)pWifiPeerStat->peerInfo +
1255 ( i * sizeof(tSirWifiPeerInfo)));
1256
Dasari Srinivas1be0c4e2014-10-19 13:03:41 +05301257 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) {
1258 pWifiPeerInfo->type = WIFI_PEER_AP;
1259 }
1260 if (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) {
1261 pWifiPeerInfo->type = WIFI_PEER_P2P_GO;
1262 }
1263
Sunil Duttc69bccb2014-05-26 21:30:20 +05301264 hddLog(VOS_TRACE_LEVEL_INFO,
1265 " %d) LL_STATS Channel Stats "
1266 " Peer Type %u "
1267 " peerMacAddress %pM "
1268 " capabilities 0x%x "
1269 " numRate %u ",
1270 i,
1271 pWifiPeerInfo->type,
1272 pWifiPeerInfo->peerMacAddress,
1273 pWifiPeerInfo->capabilities,
1274 pWifiPeerInfo->numRate);
1275 {
1276 int j;
1277 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1278 {
1279 pWifiRateStat = (tpSirWifiRateStat)
1280 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1281 ( j * sizeof(tSirWifiRateStat)));
1282
1283 hddLog(VOS_TRACE_LEVEL_INFO,
1284 " peer Rate Stats "
1285 " preamble %u "
1286 " nss %u "
1287 " bw %u "
1288 " rateMcsIdx %u "
1289 " reserved %u "
1290 " bitrate %u "
1291 " txMpdu %u "
1292 " rxMpdu %u "
1293 " mpduLost %u "
1294 " retries %u "
1295 " retriesShort %u "
1296 " retriesLong %u",
1297 pWifiRateStat->rate.preamble,
1298 pWifiRateStat->rate.nss,
1299 pWifiRateStat->rate.bw,
1300 pWifiRateStat->rate.rateMcsIdx,
1301 pWifiRateStat->rate.reserved,
1302 pWifiRateStat->rate.bitrate,
1303 pWifiRateStat->txMpdu,
1304 pWifiRateStat->rxMpdu,
1305 pWifiRateStat->mpduLost,
1306 pWifiRateStat->retries,
1307 pWifiRateStat->retriesShort,
1308 pWifiRateStat->retriesLong);
1309 }
1310 }
1311 }
1312 }
1313
1314 /*
1315 * Allocate a size of 4096 for the peer stats comprising
1316 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1317 * sizeof (tSirWifiRateStat).Each field is put with an
1318 * NL attribute.The size of 4096 is considered assuming
1319 * that number of rates shall not exceed beyond 50 with
1320 * the sizeof (tSirWifiRateStat) being 32.
1321 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301322 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1323 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301324 if (!vendor_event)
1325 {
1326 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301327 "%s: cfg80211_vendor_cmd_alloc_reply_skb failed",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301328 __func__);
1329 return;
1330 }
1331 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301332 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1333 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_PEER) ||
1334 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301335 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1336 pWifiPeerStat->numPeers))
1337 {
1338 hddLog(VOS_TRACE_LEVEL_ERROR,
1339 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1340 kfree_skb(vendor_event);
1341 return;
1342 }
1343
1344 peerInfo = nla_nest_start(vendor_event,
1345 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301346 if(!peerInfo)
1347 {
1348 hddLog(VOS_TRACE_LEVEL_ERROR,
1349 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1350 __func__);
1351 kfree_skb(vendor_event);
1352 return;
1353 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301354
1355 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1356 pWifiPeerStat->peerInfo);
1357
1358 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1359 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301360 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301361 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301362
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301363 if(!peers)
1364 {
1365 hddLog(VOS_TRACE_LEVEL_ERROR,
1366 "%s: peer stats put fail",
1367 __func__);
1368 kfree_skb(vendor_event);
1369 return;
1370 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301371 if (FALSE == put_wifi_peer_info(
1372 pWifiPeerInfo, vendor_event))
1373 {
1374 hddLog(VOS_TRACE_LEVEL_ERROR,
1375 "%s: put_wifi_peer_info put fail", __func__);
1376 kfree_skb(vendor_event);
1377 return;
1378 }
1379
1380 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1381 pWifiPeerStat->peerInfo +
1382 (i * sizeof(tSirWifiPeerInfo)) +
1383 (numRate * sizeof (tSirWifiRateStat)));
1384 nla_nest_end(vendor_event, peers);
1385 }
1386 nla_nest_end(vendor_event, peerInfo);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301387 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301388 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301389}
1390
1391/*
1392 * hdd_link_layer_process_iface_stats () - This function is called after
1393 * receiving Link Layer Interface statistics from FW.This function converts
1394 * the firmware data to the NL data and sends the same to the kernel/upper
1395 * layers.
1396 */
1397static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1398 v_VOID_t *pData)
1399{
1400 tpSirWifiIfaceStat pWifiIfaceStat;
1401 struct sk_buff *vendor_event;
1402 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1403 int status;
1404
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301405 ENTER();
1406
Sunil Duttc69bccb2014-05-26 21:30:20 +05301407 status = wlan_hdd_validate_context(pHddCtx);
1408 if (0 != status)
1409 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301410 return;
1411 }
1412 /*
1413 * Allocate a size of 4096 for the interface stats comprising
1414 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1415 * assuming that all these fit with in the limit.Please take
1416 * a call on the limit based on the data requirements on
1417 * interface statistics.
1418 */
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301419 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1420 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301421 if (!vendor_event)
1422 {
1423 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301424 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301425 return;
1426 }
1427
1428 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1429
Dino Mycle3b9536d2014-07-09 22:05:24 +05301430
1431 if (FALSE == hdd_get_interface_info( pAdapter,
1432 &pWifiIfaceStat->info))
1433 {
1434 hddLog(VOS_TRACE_LEVEL_ERROR,
1435 FL("hdd_get_interface_info get fail") );
1436 kfree_skb(vendor_event);
1437 return;
1438 }
1439
1440 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1441 vendor_event))
1442 {
1443 hddLog(VOS_TRACE_LEVEL_ERROR,
1444 FL("put_wifi_iface_stats fail") );
1445 kfree_skb(vendor_event);
1446 return;
1447 }
1448
Sunil Duttc69bccb2014-05-26 21:30:20 +05301449 hddLog(VOS_TRACE_LEVEL_INFO,
1450 "WMI_LINK_STATS_IFACE Data");
1451
1452 hddLog(VOS_TRACE_LEVEL_INFO,
1453 "LL_STATS_IFACE: "
1454 " Mode %u "
1455 " MAC %pM "
1456 " State %u "
1457 " Roaming %u "
1458 " capabilities 0x%x "
1459 " SSID %s "
1460 " BSSID %pM",
1461 pWifiIfaceStat->info.mode,
1462 pWifiIfaceStat->info.macAddr,
1463 pWifiIfaceStat->info.state,
1464 pWifiIfaceStat->info.roaming,
1465 pWifiIfaceStat->info.capabilities,
1466 pWifiIfaceStat->info.ssid,
1467 pWifiIfaceStat->info.bssid);
1468
1469 hddLog(VOS_TRACE_LEVEL_INFO,
1470 " AP country str: %c%c%c",
1471 pWifiIfaceStat->info.apCountryStr[0],
1472 pWifiIfaceStat->info.apCountryStr[1],
1473 pWifiIfaceStat->info.apCountryStr[2]);
1474
1475
1476 hddLog(VOS_TRACE_LEVEL_INFO,
1477 " Country Str Association: %c%c%c",
1478 pWifiIfaceStat->info.countryStr[0],
1479 pWifiIfaceStat->info.countryStr[1],
1480 pWifiIfaceStat->info.countryStr[2]);
1481
1482 hddLog(VOS_TRACE_LEVEL_INFO,
1483 " beaconRx %u "
1484 " mgmtRx %u "
1485 " mgmtActionRx %u "
1486 " mgmtActionTx %u "
Dino Mycle3b9536d2014-07-09 22:05:24 +05301487 " rssiMgmt %d "
1488 " rssiData %d "
1489 " rssiAck %d",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301490 pWifiIfaceStat->beaconRx,
1491 pWifiIfaceStat->mgmtRx,
1492 pWifiIfaceStat->mgmtActionRx,
1493 pWifiIfaceStat->mgmtActionTx,
1494 pWifiIfaceStat->rssiMgmt,
1495 pWifiIfaceStat->rssiData,
1496 pWifiIfaceStat->rssiAck );
1497
1498
1499 {
1500 int i;
1501 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1502 {
1503 hddLog(VOS_TRACE_LEVEL_INFO,
1504
1505 " %d) LL_STATS IFACE: "
1506 " ac: %u txMpdu: %u "
1507 " rxMpdu: %u txMcast: %u "
1508 " rxMcast: %u rxAmpdu: %u "
1509 " txAmpdu: %u mpduLost: %u "
1510 " retries: %u retriesShort: %u "
1511 " retriesLong: %u contentionTimeMin: %u "
1512 " contentionTimeMax: %u contentionTimeAvg: %u "
1513 " contentionNumSamples: %u",
1514 i,
1515 pWifiIfaceStat->AccessclassStats[i].ac,
1516 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1517 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1518 pWifiIfaceStat->AccessclassStats[i].txMcast,
1519 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1520 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1521 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1522 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1523 pWifiIfaceStat->AccessclassStats[i].retries,
1524 pWifiIfaceStat->
1525 AccessclassStats[i].retriesShort,
1526 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1527 pWifiIfaceStat->
1528 AccessclassStats[i].contentionTimeMin,
1529 pWifiIfaceStat->
1530 AccessclassStats[i].contentionTimeMax,
1531 pWifiIfaceStat->
1532 AccessclassStats[i].contentionTimeAvg,
1533 pWifiIfaceStat->
1534 AccessclassStats[i].contentionNumSamples);
1535
1536 }
1537 }
1538
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301539 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301540
1541 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301542}
1543
1544/*
1545 * hdd_link_layer_process_radio_stats () - This function is called after
1546 * receiving Link Layer Radio statistics from FW.This function converts
1547 * the firmware data to the NL data and sends the same to the kernel/upper
1548 * layers.
1549 */
1550static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1551 v_VOID_t *pData)
1552{
1553 int status, i;
1554 tpSirWifiRadioStat pWifiRadioStat;
1555 tpSirWifiChannelStats pWifiChannelStats;
1556 struct sk_buff *vendor_event;
1557 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1558 struct nlattr *chList;
1559
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301560 ENTER();
1561
Sunil Duttc69bccb2014-05-26 21:30:20 +05301562 status = wlan_hdd_validate_context(pHddCtx);
1563 if (0 != status)
1564 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301565 return;
1566 }
1567 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1568
1569 hddLog(VOS_TRACE_LEVEL_INFO,
1570 "LL_STATS_RADIO"
1571 " radio is %d onTime is %u "
1572 " txTime is %u rxTime is %u "
1573 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301574 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301575 " onTimePnoScan is %u onTimeHs20 is %u "
1576 " numChannels is %u",
1577 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1578 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1579 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301580 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301581 pWifiRadioStat->onTimeRoamScan,
1582 pWifiRadioStat->onTimePnoScan,
1583 pWifiRadioStat->onTimeHs20,
1584 pWifiRadioStat->numChannels);
1585 /*
1586 * Allocate a size of 4096 for the Radio stats comprising
1587 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1588 * (tSirWifiChannelStats).Each channel data is put with an
1589 * NL attribute.The size of 4096 is considered assuming that
1590 * number of channels shall not exceed beyond 60 with the
1591 * sizeof (tSirWifiChannelStats) being 24 bytes.
1592 */
1593
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301594 vendor_event = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy,
1595 LL_STATS_EVENT_BUF_SIZE);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301596 if (!vendor_event)
1597 {
1598 hddLog(VOS_TRACE_LEVEL_ERROR,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301599 FL("cfg80211_vendor_cmd_alloc_reply_skb failed") );
Sunil Duttc69bccb2014-05-26 21:30:20 +05301600 return;
1601 }
1602
1603 if (nla_put_u32(vendor_event,
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301604 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE,
1605 QCA_WLAN_VENDOR_ATTR_LL_STATS_TYPE_RADIO) ||
1606 nla_put_u32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301607 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1608 pWifiRadioStat->radio) ||
1609 nla_put_u32(vendor_event,
1610 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1611 pWifiRadioStat->onTime) ||
1612 nla_put_u32(vendor_event,
1613 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1614 pWifiRadioStat->txTime) ||
1615 nla_put_u32(vendor_event,
1616 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1617 pWifiRadioStat->rxTime) ||
1618 nla_put_u32(vendor_event,
1619 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1620 pWifiRadioStat->onTimeScan) ||
1621 nla_put_u32(vendor_event,
1622 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1623 pWifiRadioStat->onTimeNbd) ||
1624 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301625 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1626 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301627 nla_put_u32(vendor_event,
1628 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1629 pWifiRadioStat->onTimeRoamScan) ||
1630 nla_put_u32(vendor_event,
1631 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1632 pWifiRadioStat->onTimePnoScan) ||
1633 nla_put_u32(vendor_event,
1634 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1635 pWifiRadioStat->onTimeHs20) ||
1636 nla_put_u32(vendor_event,
1637 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1638 pWifiRadioStat->numChannels))
1639 {
1640 hddLog(VOS_TRACE_LEVEL_ERROR,
1641 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1642 kfree_skb(vendor_event);
1643 return ;
1644 }
1645
1646 chList = nla_nest_start(vendor_event,
1647 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301648 if(!chList)
1649 {
1650 hddLog(VOS_TRACE_LEVEL_ERROR,
1651 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1652 __func__);
1653 kfree_skb(vendor_event);
1654 return;
1655 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301656 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1657 {
1658 struct nlattr *chInfo;
1659
1660 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1661 pWifiRadioStat->channels +
1662 (i * sizeof(tSirWifiChannelStats)));
1663
1664 hddLog(VOS_TRACE_LEVEL_INFO,
1665 " %d) Channel Info"
1666 " width is %u "
1667 " CenterFreq %u "
1668 " CenterFreq0 %u "
1669 " CenterFreq1 %u "
1670 " onTime %u "
1671 " ccaBusyTime %u",
1672 i,
1673 pWifiChannelStats->channel.width,
1674 pWifiChannelStats->channel.centerFreq,
1675 pWifiChannelStats->channel.centerFreq0,
1676 pWifiChannelStats->channel.centerFreq1,
1677 pWifiChannelStats->onTime,
1678 pWifiChannelStats->ccaBusyTime);
1679
1680
1681 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301682 if(!chInfo)
1683 {
1684 hddLog(VOS_TRACE_LEVEL_ERROR,
1685 "%s: failed to put chInfo",
1686 __func__);
1687 kfree_skb(vendor_event);
1688 return;
1689 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301690
1691 if (nla_put_u32(vendor_event,
1692 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1693 pWifiChannelStats->channel.width) ||
1694 nla_put_u32(vendor_event,
1695 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1696 pWifiChannelStats->channel.centerFreq) ||
1697 nla_put_u32(vendor_event,
1698 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1699 pWifiChannelStats->channel.centerFreq0) ||
1700 nla_put_u32(vendor_event,
1701 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1702 pWifiChannelStats->channel.centerFreq1) ||
1703 nla_put_u32(vendor_event,
1704 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1705 pWifiChannelStats->onTime) ||
1706 nla_put_u32(vendor_event,
1707 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1708 pWifiChannelStats->ccaBusyTime))
1709 {
1710 hddLog(VOS_TRACE_LEVEL_ERROR,
1711 FL("cfg80211_vendor_event_alloc failed") );
1712 kfree_skb(vendor_event);
1713 return ;
1714 }
1715 nla_nest_end(vendor_event, chInfo);
1716 }
1717 nla_nest_end(vendor_event, chList);
1718
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301719 cfg80211_vendor_cmd_reply(vendor_event);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301720
1721 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301722 return;
1723}
1724
1725/*
1726 * hdd_link_layer_stats_ind_callback () - This function is called after
1727 * receiving Link Layer indications from FW.This callback converts the firmware
1728 * data to the NL data and send the same to the kernel/upper layers.
1729 */
1730static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1731 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301732 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301733{
Dino Mycled3d50022014-07-07 12:58:25 +05301734 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1735 hdd_adapter_t *pAdapter = NULL;
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301736 struct hdd_ll_stats_context *context;
Dino Mycled3d50022014-07-07 12:58:25 +05301737 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301738 int status;
1739
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301740 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301741
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301742 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301743 if (0 != status)
1744 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301745 return;
1746 }
1747
Dino Mycled3d50022014-07-07 12:58:25 +05301748 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1749 if (NULL == pAdapter)
1750 {
1751 hddLog(VOS_TRACE_LEVEL_ERROR,
1752 FL(" MAC address %pM does not exist with host"),
1753 macAddr);
1754 return;
1755 }
1756
Sunil Duttc69bccb2014-05-26 21:30:20 +05301757 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301758 "%s: Interface: %s LLStats indType: %d", __func__,
1759 pAdapter->dev->name, indType);
1760
Sunil Duttc69bccb2014-05-26 21:30:20 +05301761 switch (indType)
1762 {
1763 case SIR_HAL_LL_STATS_RESULTS_RSP:
1764 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301765 hddLog(VOS_TRACE_LEVEL_INFO,
1766 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1767 hddLog(VOS_TRACE_LEVEL_INFO,
1768 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1769 linkLayerStatsResults->paramId);
1770 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301771 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1772 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301773 hddLog(VOS_TRACE_LEVEL_INFO,
1774 "LL_STATS RESULTS RESPONSE respId = %u",
1775 linkLayerStatsResults->respId);
1776 hddLog(VOS_TRACE_LEVEL_INFO,
1777 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1778 linkLayerStatsResults->moreResultToFollow);
1779 hddLog(VOS_TRACE_LEVEL_INFO,
1780 "LL_STATS RESULTS RESPONSE result = %p",
1781 linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301782 spin_lock(&hdd_context_lock);
1783 context = &pHddCtx->ll_stats_context;
1784 /* validate response received from target */
1785 if ((context->request_id != linkLayerStatsResults->respId) ||
1786 !(context->request_bitmap & linkLayerStatsResults->paramId))
1787 {
1788 spin_unlock(&hdd_context_lock);
1789 hddLog(LOGE,
1790 FL("Error : Request id %d response id %d request bitmap 0x%x"
1791 "response bitmap 0x%x"),
1792 context->request_id, linkLayerStatsResults->respId,
1793 context->request_bitmap, linkLayerStatsResults->paramId);
1794 return;
1795 }
1796 spin_unlock(&hdd_context_lock);
1797
Sunil Duttc69bccb2014-05-26 21:30:20 +05301798 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1799 {
1800 hdd_link_layer_process_radio_stats(pAdapter,
1801 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301802 spin_lock(&hdd_context_lock);
1803 context->request_bitmap &= ~(WMI_LINK_STATS_RADIO);
1804 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301805 }
1806 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1807 {
1808 hdd_link_layer_process_iface_stats(pAdapter,
1809 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301810 spin_lock(&hdd_context_lock);
1811 context->request_bitmap &= ~(WMI_LINK_STATS_IFACE);
1812 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301813 }
1814 else if ( linkLayerStatsResults->paramId &
1815 WMI_LINK_STATS_ALL_PEER )
1816 {
1817 hdd_link_layer_process_peer_stats(pAdapter,
1818 (v_VOID_t *)linkLayerStatsResults->result);
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301819 spin_lock(&hdd_context_lock);
1820 context->request_bitmap &= ~(WMI_LINK_STATS_ALL_PEER);
1821 spin_unlock(&hdd_context_lock);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301822 } /* WMI_LINK_STATS_ALL_PEER */
1823 else
1824 {
1825 hddLog(VOS_TRACE_LEVEL_ERROR,
1826 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1827 }
1828
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301829 spin_lock(&hdd_context_lock);
1830 /* complete response event if all requests are completed */
1831 if (0 == context->request_bitmap)
1832 complete(&context->response_event);
1833 spin_unlock(&hdd_context_lock);
1834
Sunil Duttc69bccb2014-05-26 21:30:20 +05301835 break;
1836 }
1837 default:
1838 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1839 break;
1840 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301841
1842 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301843 return;
1844}
1845
1846const struct
1847nla_policy
1848qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1849{
1850 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1851 { .type = NLA_U32 },
1852 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1853 { .type = NLA_U32 },
1854};
1855
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301856static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1857 struct wireless_dev *wdev,
1858 const void *data,
1859 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301860{
1861 int status;
1862 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301863 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301864 struct net_device *dev = wdev->netdev;
1865 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1866 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1867
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301868 ENTER();
1869
Sunil Duttc69bccb2014-05-26 21:30:20 +05301870 status = wlan_hdd_validate_context(pHddCtx);
1871 if (0 != status)
1872 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301873 return -EINVAL;
1874 }
1875
1876 if (NULL == pAdapter)
1877 {
1878 hddLog(VOS_TRACE_LEVEL_ERROR,
1879 FL("HDD adapter is Null"));
1880 return -ENODEV;
1881 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301882 /* check the LLStats Capability */
1883 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1884 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1885 {
1886 hddLog(VOS_TRACE_LEVEL_ERROR,
1887 FL("Link Layer Statistics not supported by Firmware"));
1888 return -EINVAL;
1889 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301890
1891 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1892 (struct nlattr *)data,
1893 data_len, qca_wlan_vendor_ll_set_policy))
1894 {
1895 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1896 return -EINVAL;
1897 }
1898 if (!tb_vendor
1899 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1900 {
1901 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1902 return -EINVAL;
1903 }
1904 if (!tb_vendor[
1905 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1906 {
1907 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1908 return -EINVAL;
1909 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301910 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301911 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301912
Dino Mycledf0a5d92014-07-04 09:41:55 +05301913 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301914 nla_get_u32(
1915 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1916
Dino Mycledf0a5d92014-07-04 09:41:55 +05301917 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301918 nla_get_u32(
1919 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1920
Dino Mycled3d50022014-07-07 12:58:25 +05301921 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1922 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301923
1924
1925 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301926 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301927 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301928 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301929 hddLog(VOS_TRACE_LEVEL_INFO,
1930 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301931 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301932 hddLog(VOS_TRACE_LEVEL_INFO,
1933 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301934 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301935
1936 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1937 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301938 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301939 {
1940 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1941 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301942 return -EINVAL;
1943
1944 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301945
Sunil Duttc69bccb2014-05-26 21:30:20 +05301946 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301947 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301948 {
1949 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1950 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301951 return -EINVAL;
1952 }
1953
1954 pAdapter->isLinkLayerStatsSet = 1;
1955
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301956 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301957 return 0;
1958}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301959static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1960 struct wireless_dev *wdev,
1961 const void *data,
1962 int data_len)
1963{
1964 int ret = 0;
1965
1966 vos_ssr_protect(__func__);
1967 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1968 vos_ssr_unprotect(__func__);
1969
1970 return ret;
1971}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301972
1973const struct
1974nla_policy
1975qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1976{
1977 /* Unsigned 32bit value provided by the caller issuing the GET stats
1978 * command. When reporting
1979 * the stats results, the driver uses the same value to indicate
1980 * which GET request the results
1981 * correspond to.
1982 */
1983 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1984
1985 /* Unsigned 32bit value . bit mask to identify what statistics are
1986 requested for retrieval */
1987 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1988};
1989
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301990static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1991 struct wireless_dev *wdev,
1992 const void *data,
1993 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301994{
mukul sharma4bd8d2e2015-08-13 20:33:25 +05301995 unsigned long rc;
1996 struct hdd_ll_stats_context *context;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301997 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1998 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301999 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302000 struct net_device *dev = wdev->netdev;
2001 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05302002 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302003 int status;
2004
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302005 ENTER();
2006
Sunil Duttc69bccb2014-05-26 21:30:20 +05302007 status = wlan_hdd_validate_context(pHddCtx);
2008 if (0 != status)
2009 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302010 return -EINVAL ;
2011 }
2012
2013 if (NULL == pAdapter)
2014 {
2015 hddLog(VOS_TRACE_LEVEL_FATAL,
2016 "%s: HDD adapter is Null", __func__);
2017 return -ENODEV;
2018 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302019
2020 if (pHddStaCtx == NULL)
2021 {
2022 hddLog(VOS_TRACE_LEVEL_FATAL,
2023 "%s: HddStaCtx is Null", __func__);
2024 return -ENODEV;
2025 }
2026
Dino Mycledf0a5d92014-07-04 09:41:55 +05302027 /* check the LLStats Capability */
2028 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2029 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2030 {
2031 hddLog(VOS_TRACE_LEVEL_ERROR,
2032 FL("Link Layer Statistics not supported by Firmware"));
2033 return -EINVAL;
2034 }
2035
Sunil Duttc69bccb2014-05-26 21:30:20 +05302036
2037 if (!pAdapter->isLinkLayerStatsSet)
2038 {
2039 hddLog(VOS_TRACE_LEVEL_FATAL,
2040 "%s: isLinkLayerStatsSet : %d",
2041 __func__, pAdapter->isLinkLayerStatsSet);
2042 return -EINVAL;
2043 }
2044
Mukul Sharma10313ba2015-07-29 19:14:39 +05302045 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2046 {
2047 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2048 "%s: Roaming in progress, so unable to proceed this request", __func__);
2049 return -EBUSY;
2050 }
2051
Sunil Duttc69bccb2014-05-26 21:30:20 +05302052 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2053 (struct nlattr *)data,
2054 data_len, qca_wlan_vendor_ll_get_policy))
2055 {
2056 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2057 return -EINVAL;
2058 }
2059
2060 if (!tb_vendor
2061 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2062 {
2063 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2064 return -EINVAL;
2065 }
2066
2067 if (!tb_vendor
2068 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2069 {
2070 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2071 return -EINVAL;
2072 }
2073
Sunil Duttc69bccb2014-05-26 21:30:20 +05302074
Dino Mycledf0a5d92014-07-04 09:41:55 +05302075 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302076 nla_get_u32( tb_vendor[
2077 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302078 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302079 nla_get_u32( tb_vendor[
2080 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2081
Dino Mycled3d50022014-07-07 12:58:25 +05302082 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2083 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302084
2085 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302086 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302087 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302088 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302089 hddLog(VOS_TRACE_LEVEL_INFO,
2090 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302091 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302092
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302093 spin_lock(&hdd_context_lock);
2094 context = &pHddCtx->ll_stats_context;
2095 context->request_id = linkLayerStatsGetReq.reqId;
2096 context->request_bitmap = linkLayerStatsGetReq.paramIdMask;
2097 INIT_COMPLETION(context->response_event);
2098 spin_unlock(&hdd_context_lock);
2099
Sunil Duttc69bccb2014-05-26 21:30:20 +05302100 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302101 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302102 {
2103 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2104 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302105 return -EINVAL;
2106 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302107
mukul sharma4bd8d2e2015-08-13 20:33:25 +05302108 rc = wait_for_completion_timeout(&context->response_event,
2109 msecs_to_jiffies(WLAN_WAIT_TIME_LL_STATS));
2110 if (!rc)
2111 {
2112 hddLog(LOGE,
2113 FL("Target response timed out request id %d request bitmap 0x%x"),
2114 context->request_id, context->request_bitmap);
2115 return -ETIMEDOUT;
2116 }
2117
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302118 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302119 return 0;
2120}
2121
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302122static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2123 struct wireless_dev *wdev,
2124 const void *data,
2125 int data_len)
2126{
2127 int ret = 0;
2128
2129 vos_ssr_protect(__func__);
2130 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
2131 vos_ssr_unprotect(__func__);
2132
2133 return ret;
2134}
2135
Sunil Duttc69bccb2014-05-26 21:30:20 +05302136const struct
2137nla_policy
2138qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
2139{
2140 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
2141 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
2142 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
2143 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
2144};
2145
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302146static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2147 struct wireless_dev *wdev,
2148 const void *data,
2149 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302150{
2151 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2152 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302153 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302154 struct net_device *dev = wdev->netdev;
2155 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2156 u32 statsClearReqMask;
2157 u8 stopReq;
2158 int status;
2159
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302160 ENTER();
2161
Sunil Duttc69bccb2014-05-26 21:30:20 +05302162 status = wlan_hdd_validate_context(pHddCtx);
2163 if (0 != status)
2164 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302165 return -EINVAL;
2166 }
2167
2168 if (NULL == pAdapter)
2169 {
2170 hddLog(VOS_TRACE_LEVEL_FATAL,
2171 "%s: HDD adapter is Null", __func__);
2172 return -ENODEV;
2173 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302174 /* check the LLStats Capability */
2175 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2176 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2177 {
2178 hddLog(VOS_TRACE_LEVEL_ERROR,
2179 FL("Enable LLStats Capability"));
2180 return -EINVAL;
2181 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302182
2183 if (!pAdapter->isLinkLayerStatsSet)
2184 {
2185 hddLog(VOS_TRACE_LEVEL_FATAL,
2186 "%s: isLinkLayerStatsSet : %d",
2187 __func__, pAdapter->isLinkLayerStatsSet);
2188 return -EINVAL;
2189 }
2190
2191 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2192 (struct nlattr *)data,
2193 data_len, qca_wlan_vendor_ll_clr_policy))
2194 {
2195 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2196 return -EINVAL;
2197 }
2198
2199 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2200
2201 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2202 {
2203 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2204 return -EINVAL;
2205
2206 }
2207
Sunil Duttc69bccb2014-05-26 21:30:20 +05302208
Dino Mycledf0a5d92014-07-04 09:41:55 +05302209 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302210 nla_get_u32(
2211 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2212
Dino Mycledf0a5d92014-07-04 09:41:55 +05302213 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302214 nla_get_u8(
2215 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2216
2217 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302218 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302219
Dino Mycled3d50022014-07-07 12:58:25 +05302220 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2221 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302222
2223 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302224 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302225 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302226 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302227 hddLog(VOS_TRACE_LEVEL_INFO,
2228 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302229 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302230 hddLog(VOS_TRACE_LEVEL_INFO,
2231 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302232 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302233
2234 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302235 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302236 {
2237 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302238 hdd_station_ctx_t *pHddStaCtx;
2239
2240 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2241 if (VOS_STATUS_SUCCESS !=
2242 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2243 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2244 {
2245 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2246 "WLANTL_ClearInterfaceStats Failed", __func__);
2247 return -EINVAL;
2248 }
2249 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2250 (statsClearReqMask & WIFI_STATS_IFACE)) {
2251 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2252 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2253 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2254 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2255 }
2256
Sunil Duttc69bccb2014-05-26 21:30:20 +05302257 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2258 2 * sizeof(u32) +
2259 NLMSG_HDRLEN);
2260
2261 if (temp_skbuff != NULL)
2262 {
2263
2264 if (nla_put_u32(temp_skbuff,
2265 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2266 statsClearReqMask) ||
2267 nla_put_u32(temp_skbuff,
2268 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2269 stopReq))
2270 {
2271 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2272 kfree_skb(temp_skbuff);
2273 return -EINVAL;
2274 }
2275 /* If the ask is to stop the stats collection as part of clear
2276 * (stopReq = 1) , ensure that no further requests of get
2277 * go to the firmware by having isLinkLayerStatsSet set to 0.
2278 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302279 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302280 * case the firmware is just asked to clear the statistics.
2281 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302282 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302283 pAdapter->isLinkLayerStatsSet = 0;
2284 return cfg80211_vendor_cmd_reply(temp_skbuff);
2285 }
2286 return -ENOMEM;
2287 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302288
2289 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302290 return -EINVAL;
2291}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302292static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2293 struct wireless_dev *wdev,
2294 const void *data,
2295 int data_len)
2296{
2297 int ret = 0;
2298
2299 vos_ssr_protect(__func__);
2300 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2301 vos_ssr_unprotect(__func__);
2302
2303 return ret;
2304
2305
2306}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302307#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2308
Dino Mycle6fb96c12014-06-10 11:52:40 +05302309#ifdef WLAN_FEATURE_EXTSCAN
2310static const struct nla_policy
2311wlan_hdd_extscan_config_policy
2312 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2313{
2314 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2315 { .type = NLA_U32 },
2316 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2317 { .type = NLA_U32 },
2318 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2319 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2320 { .type = NLA_U32 },
2321 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2322 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2323
2324 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2325 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2326 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2327 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2328 { .type = NLA_U8 },
2329 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2330 { .type = NLA_U32 },
2331 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2332 { .type = NLA_U32 },
2333 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2334 { .type = NLA_U32 },
2335 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
2336 { .type = NLA_U8 },
2337 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2338 { .type = NLA_U8 },
2339 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2340 { .type = NLA_U8 },
2341
2342 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2343 { .type = NLA_U32 },
2344 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2345 { .type = NLA_UNSPEC },
2346 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2347 { .type = NLA_S32 },
2348 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2349 { .type = NLA_S32 },
2350 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2351 { .type = NLA_U32 },
2352 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2353 { .type = NLA_U32 },
2354 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
2355 { .type = NLA_U32 },
2356 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
2357 = { .type = NLA_U32 },
2358 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
2359 { .type = NLA_U32 },
2360 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
2361 NLA_U32 },
2362};
2363
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302364/**
2365 * wlan_hdd_cfg80211_extscan_get_capabilities_rsp() - response from target
2366 * @ctx: hdd global context
2367 * @data: capabilities data
2368 *
2369 * Return: none
2370 */
2371static void
2372wlan_hdd_cfg80211_extscan_get_capabilities_rsp(void *ctx, void *pMsg)
Dino Mycle6fb96c12014-06-10 11:52:40 +05302373{
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302374 struct hdd_ext_scan_context *context;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302375 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302376 tSirEXTScanCapabilitiesEvent *data =
2377 (tSirEXTScanCapabilitiesEvent *) pMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05302378
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302379 ENTER();
2380
2381 if (wlan_hdd_validate_context(pHddCtx))
2382 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302383 return;
2384 }
2385
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302386 if (!pMsg)
2387 {
2388 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2389 return;
2390 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302391
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302392 vos_spin_lock_acquire(&hdd_context_lock);
2393
2394 context = &pHddCtx->ext_scan_context;
2395 /* validate response received from target*/
2396 if (context->request_id != data->requestId)
2397 {
2398 vos_spin_lock_release(&hdd_context_lock);
2399 hddLog(LOGE,
2400 FL("Target response id did not match: request_id %d resposne_id %d"),
2401 context->request_id, data->requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302402 return;
2403 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302404 else
2405 {
2406 context->capability_response = *data;
2407 complete(&context->response_event);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302408 }
2409
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302410 vos_spin_lock_release(&hdd_context_lock);
Dino Mycle6fb96c12014-06-10 11:52:40 +05302411
Dino Mycle6fb96c12014-06-10 11:52:40 +05302412 return;
2413}
2414
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05302415/*
2416 * define short names for the global vendor params
2417 * used by wlan_hdd_send_ext_scan_capability()
2418 */
2419#define PARAM_REQUEST_ID \
2420 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID
2421#define PARAM_STATUS \
2422 QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS
2423#define MAX_SCAN_CACHE_SIZE \
2424 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE
2425#define MAX_SCAN_BUCKETS \
2426 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS
2427#define MAX_AP_CACHE_PER_SCAN \
2428 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN
2429#define MAX_RSSI_SAMPLE_SIZE \
2430 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE
2431#define MAX_SCAN_RPT_THRHOLD \
2432 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD
2433#define MAX_HOTLIST_BSSIDS \
2434 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_BSSIDS
2435#define MAX_BSSID_HISTORY_ENTRIES \
2436 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES
2437#define MAX_HOTLIST_SSIDS \
2438 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_SSIDS
2439
2440static int wlan_hdd_send_ext_scan_capability(void *ctx)
2441{
2442 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2443 struct sk_buff *skb = NULL;
2444 int ret;
2445 tSirEXTScanCapabilitiesEvent *data;
2446 tANI_U32 nl_buf_len;
2447
2448 ret = wlan_hdd_validate_context(pHddCtx);
2449 if (0 != ret)
2450 {
2451 return ret;
2452 }
2453
2454 data = &(pHddCtx->ext_scan_context.capability_response);
2455
2456 nl_buf_len = NLMSG_HDRLEN;
2457 nl_buf_len += (sizeof(data->requestId) + NLA_HDRLEN) +
2458 (sizeof(data->status) + NLA_HDRLEN) +
2459 (sizeof(data->scanCacheSize) + NLA_HDRLEN) +
2460 (sizeof(data->scanBuckets) + NLA_HDRLEN) +
2461 (sizeof(data->maxApPerScan) + NLA_HDRLEN) +
2462 (sizeof(data->maxRssiSampleSize) + NLA_HDRLEN) +
2463 (sizeof(data->maxScanReportingThreshold) + NLA_HDRLEN) +
2464 (sizeof(data->maxHotlistAPs) + NLA_HDRLEN) +
2465 (sizeof(data->maxBsidHistoryEntries) + NLA_HDRLEN) +
2466 (sizeof(data->maxHotlistSSIDs) + NLA_HDRLEN);
2467
2468 skb = cfg80211_vendor_cmd_alloc_reply_skb(pHddCtx->wiphy, nl_buf_len);
2469
2470 if (!skb)
2471 {
2472 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
2473 return -ENOMEM;
2474 }
2475
2476 hddLog(LOG1, "Req Id (%u) Status (%u)", data->requestId, data->status);
2477 hddLog(LOG1, "Scan cache size (%u) Scan buckets (%u) Max AP per scan (%u)",
2478 data->scanCacheSize, data->scanBuckets, data->maxApPerScan);
2479 hddLog(LOG1, "max_rssi_sample_size (%u) max_scan_reporting_threshold (%u)",
2480 data->maxRssiSampleSize, data->maxScanReportingThreshold);
2481 hddLog(LOG1, "max_hotlist_bssids (%u) max_bssid_history_entries (%u)"
2482 "max_hotlist_ssids (%u)", data->maxHotlistAPs,
2483 data->maxBsidHistoryEntries, data->maxHotlistSSIDs);
2484
2485 if (nla_put_u32(skb, PARAM_REQUEST_ID, data->requestId) ||
2486 nla_put_u32(skb, PARAM_STATUS, data->status) ||
2487 nla_put_u32(skb, MAX_SCAN_CACHE_SIZE, data->scanCacheSize) ||
2488 nla_put_u32(skb, MAX_SCAN_BUCKETS, data->scanBuckets) ||
2489 nla_put_u32(skb, MAX_AP_CACHE_PER_SCAN,
2490 data->maxApPerScan) ||
2491 nla_put_u32(skb, MAX_RSSI_SAMPLE_SIZE,
2492 data->maxRssiSampleSize) ||
2493 nla_put_u32(skb, MAX_SCAN_RPT_THRHOLD,
2494 data->maxScanReportingThreshold) ||
2495 nla_put_u32(skb, MAX_HOTLIST_BSSIDS, data->maxHotlistAPs) ||
2496 nla_put_u32(skb, MAX_BSSID_HISTORY_ENTRIES,
2497 data->maxBsidHistoryEntries) ||
2498 nla_put_u32(skb, MAX_HOTLIST_SSIDS, data->maxHotlistSSIDs))
2499 {
2500 hddLog(LOGE, FL("nla put fail"));
2501 goto nla_put_failure;
2502 }
2503
2504 cfg80211_vendor_cmd_reply(skb);
2505 return 0;
2506
2507nla_put_failure:
2508 kfree_skb(skb);
2509 return -EINVAL;;
2510}
2511
2512/*
2513 * done with short names for the global vendor params
2514 * used by wlan_hdd_send_ext_scan_capability()
2515 */
2516#undef PARAM_REQUEST_ID
2517#undef PARAM_STATUS
2518#undef MAX_SCAN_CACHE_SIZE
2519#undef MAX_SCAN_BUCKETS
2520#undef MAX_AP_CACHE_PER_SCAN
2521#undef MAX_RSSI_SAMPLE_SIZE
2522#undef MAX_SCAN_RPT_THRHOLD
2523#undef MAX_HOTLIST_BSSIDS
2524#undef MAX_SIGNIFICANT_WIFI_CHANGE_APS
2525#undef MAX_BSSID_HISTORY_ENTRIES
2526#undef MAX_HOTLIST_SSIDS
Dino Mycle6fb96c12014-06-10 11:52:40 +05302527
2528static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2529{
2530 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2531 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2532 struct sk_buff *skb = NULL;
2533 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2534
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302535 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302536
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302537 if (wlan_hdd_validate_context(pHddCtx)){
2538 return;
2539 }
2540 if (!pMsg)
2541 {
2542 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302543 return;
2544 }
2545
2546 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302547#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2548 NULL,
2549#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302550 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2551 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2552 GFP_KERNEL);
2553
2554 if (!skb) {
2555 hddLog(VOS_TRACE_LEVEL_ERROR,
2556 FL("cfg80211_vendor_event_alloc failed"));
2557 return;
2558 }
2559 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2560 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2561 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2562
2563 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2564 pData->requestId) ||
2565 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2566 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2567 goto nla_put_failure;
2568 }
2569
2570 /*
2571 * Store the Request ID for comparing with the requestID obtained
2572 * in other requests.HDD shall return a failure is the extscan_stop
2573 * request is issued with a different requestId as that of the
2574 * extscan_start request. Also, This requestId shall be used while
2575 * indicating the full scan results to the upper layers.
2576 * The requestId is stored with the assumption that the firmware
2577 * shall return the ext scan start request's requestId in ext scan
2578 * start response.
2579 */
2580 if (pData->status == 0)
2581 pMac->sme.extScanStartReqId = pData->requestId;
2582
2583
2584 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302585 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302586 return;
2587
2588nla_put_failure:
2589 kfree_skb(skb);
2590 return;
2591}
2592
2593
2594static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2595{
2596 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2597 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2598 struct sk_buff *skb = NULL;
2599
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302600 ENTER();
2601
2602 if (wlan_hdd_validate_context(pHddCtx)){
2603 return;
2604 }
2605 if (!pMsg)
2606 {
2607 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302608 return;
2609 }
2610
2611 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302612#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2613 NULL,
2614#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302615 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2616 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2617 GFP_KERNEL);
2618
2619 if (!skb) {
2620 hddLog(VOS_TRACE_LEVEL_ERROR,
2621 FL("cfg80211_vendor_event_alloc failed"));
2622 return;
2623 }
2624 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2625 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2626
2627 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2628 pData->requestId) ||
2629 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2630 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2631 goto nla_put_failure;
2632 }
2633
2634 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302635 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302636 return;
2637
2638nla_put_failure:
2639 kfree_skb(skb);
2640 return;
2641}
2642
2643
2644static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2645 void *pMsg)
2646{
2647 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2648 struct sk_buff *skb = NULL;
2649 tpSirEXTScanSetBssidHotListRspParams pData =
2650 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2651
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302652 ENTER();
2653
2654 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302655 return;
2656 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302657 if (!pMsg)
2658 {
2659 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2660 return;
2661 }
2662
Dino Mycle6fb96c12014-06-10 11:52:40 +05302663 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302664#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2665 NULL,
2666#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302667 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2668 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2669 GFP_KERNEL);
2670
2671 if (!skb) {
2672 hddLog(VOS_TRACE_LEVEL_ERROR,
2673 FL("cfg80211_vendor_event_alloc failed"));
2674 return;
2675 }
2676 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2677 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2678 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2679
2680 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2681 pData->requestId) ||
2682 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2683 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2684 goto nla_put_failure;
2685 }
2686
2687 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302688 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302689 return;
2690
2691nla_put_failure:
2692 kfree_skb(skb);
2693 return;
2694}
2695
2696static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2697 void *pMsg)
2698{
2699 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2700 struct sk_buff *skb = NULL;
2701 tpSirEXTScanResetBssidHotlistRspParams pData =
2702 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2703
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302704 ENTER();
2705
2706 if (wlan_hdd_validate_context(pHddCtx)) {
2707 return;
2708 }
2709 if (!pMsg)
2710 {
2711 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302712 return;
2713 }
2714
2715 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302716#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2717 NULL,
2718#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302719 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2720 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2721 GFP_KERNEL);
2722
2723 if (!skb) {
2724 hddLog(VOS_TRACE_LEVEL_ERROR,
2725 FL("cfg80211_vendor_event_alloc failed"));
2726 return;
2727 }
2728 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2729 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2730
2731 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2732 pData->requestId) ||
2733 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2734 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2735 goto nla_put_failure;
2736 }
2737
2738 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302739 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302740 return;
2741
2742nla_put_failure:
2743 kfree_skb(skb);
2744 return;
2745}
2746
2747
2748static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2749 void *pMsg)
2750{
2751 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2752 struct sk_buff *skb = NULL;
2753 tpSirEXTScanSetSignificantChangeRspParams pData =
2754 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2755
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302756 ENTER();
2757
2758 if (wlan_hdd_validate_context(pHddCtx)) {
2759 return;
2760 }
2761 if (!pMsg)
2762 {
2763 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302764 return;
2765 }
2766
2767 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302768#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2769 NULL,
2770#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302771 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2772 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2773 GFP_KERNEL);
2774
2775 if (!skb) {
2776 hddLog(VOS_TRACE_LEVEL_ERROR,
2777 FL("cfg80211_vendor_event_alloc failed"));
2778 return;
2779 }
2780 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2781 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2782 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2783
2784 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2785 pData->requestId) ||
2786 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2787 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2788 goto nla_put_failure;
2789 }
2790
2791 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302792 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302793 return;
2794
2795nla_put_failure:
2796 kfree_skb(skb);
2797 return;
2798}
2799
2800
2801static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2802 void *pMsg)
2803{
2804 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2805 struct sk_buff *skb = NULL;
2806 tpSirEXTScanResetSignificantChangeRspParams pData =
2807 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2808
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302809 ENTER();
2810
2811 if (wlan_hdd_validate_context(pHddCtx)) {
2812 return;
2813 }
2814 if (!pMsg)
2815 {
2816 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302817 return;
2818 }
2819
2820 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302821#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2822 NULL,
2823#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302824 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2825 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2826 GFP_KERNEL);
2827
2828 if (!skb) {
2829 hddLog(VOS_TRACE_LEVEL_ERROR,
2830 FL("cfg80211_vendor_event_alloc failed"));
2831 return;
2832 }
2833 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2834 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2835 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2836
2837 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2838 pData->requestId) ||
2839 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2840 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2841 goto nla_put_failure;
2842 }
2843
2844 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302845 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302846 return;
2847
2848nla_put_failure:
2849 kfree_skb(skb);
2850 return;
2851}
2852
2853static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2854 void *pMsg)
2855{
2856 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2857 struct sk_buff *skb = NULL;
2858 tANI_U32 i = 0, j, resultsPerEvent;
2859 tANI_S32 totalResults;
2860 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2861 tpSirWifiScanResult pSirWifiScanResult;
2862
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302863 ENTER();
2864
2865 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302866 return;
2867 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302868 if (!pMsg)
2869 {
2870 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2871 return;
2872 }
2873
Dino Mycle6fb96c12014-06-10 11:52:40 +05302874 totalResults = pData->numOfAps;
2875 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2876 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2877 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2878
2879 do{
2880 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2881 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2882 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2883
2884 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302885#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2886 NULL,
2887#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302888 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2889 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2890 GFP_KERNEL);
2891
2892 if (!skb) {
2893 hddLog(VOS_TRACE_LEVEL_ERROR,
2894 FL("cfg80211_vendor_event_alloc failed"));
2895 return;
2896 }
2897
2898 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2899
2900 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2901 pData->requestId) ||
2902 nla_put_u32(skb,
2903 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2904 resultsPerEvent)) {
2905 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2906 goto fail;
2907 }
2908 if (nla_put_u8(skb,
2909 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2910 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2911 {
2912 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2913 goto fail;
2914 }
2915
2916 if (resultsPerEvent) {
2917 struct nlattr *aps;
2918
2919 aps = nla_nest_start(skb,
2920 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2921 if (!aps)
2922 {
2923 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2924 goto fail;
2925 }
2926
2927 for (j = 0; j < resultsPerEvent; j++, i++) {
2928 struct nlattr *ap;
2929 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2930 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2931
2932 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2933 "Ssid (%s)"
2934 "Bssid: %pM "
2935 "Channel (%u)"
2936 "Rssi (%d)"
2937 "RTT (%u)"
2938 "RTT_SD (%u)",
2939 i,
2940 pSirWifiScanResult->ts,
2941 pSirWifiScanResult->ssid,
2942 pSirWifiScanResult->bssid,
2943 pSirWifiScanResult->channel,
2944 pSirWifiScanResult->rssi,
2945 pSirWifiScanResult->rtt,
2946 pSirWifiScanResult->rtt_sd);
2947
2948 ap = nla_nest_start(skb, j + 1);
2949 if (!ap)
2950 {
2951 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2952 goto fail;
2953 }
2954
2955 if (nla_put_u64(skb,
2956 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2957 pSirWifiScanResult->ts) )
2958 {
2959 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2960 goto fail;
2961 }
2962 if (nla_put(skb,
2963 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2964 sizeof(pSirWifiScanResult->ssid),
2965 pSirWifiScanResult->ssid) )
2966 {
2967 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2968 goto fail;
2969 }
2970 if (nla_put(skb,
2971 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2972 sizeof(pSirWifiScanResult->bssid),
2973 pSirWifiScanResult->bssid) )
2974 {
2975 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2976 goto fail;
2977 }
2978 if (nla_put_u32(skb,
2979 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2980 pSirWifiScanResult->channel) )
2981 {
2982 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2983 goto fail;
2984 }
Dasari Srinivas90747d72014-10-08 12:16:15 +05302985 if (nla_put_s32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302986 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2987 pSirWifiScanResult->rssi) )
2988 {
2989 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2990 goto fail;
2991 }
2992 if (nla_put_u32(skb,
2993 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2994 pSirWifiScanResult->rtt) )
2995 {
2996 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2997 goto fail;
2998 }
2999 if (nla_put_u32(skb,
3000 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3001 pSirWifiScanResult->rtt_sd))
3002 {
3003 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3004 goto fail;
3005 }
3006
3007 nla_nest_end(skb, ap);
3008 }
3009 nla_nest_end(skb, aps);
3010
3011 }
3012 cfg80211_vendor_event(skb, GFP_KERNEL);
3013 } while (totalResults > 0);
3014
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303015 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303016 return;
3017fail:
3018 kfree_skb(skb);
3019 return;
3020}
3021
3022static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
3023 void *pMsg)
3024{
3025 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
3026 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3027 struct sk_buff *skb = NULL;
3028 tANI_U32 i;
3029
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303030 ENTER();
3031
3032 if (wlan_hdd_validate_context(pHddCtx)) {
3033 return;
3034 }
3035 if (!pMsg)
3036 {
3037 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303038 return;
3039 }
3040
3041 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303042#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3043 NULL,
3044#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303045 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3046 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
3047 GFP_KERNEL);
3048
3049 if (!skb) {
3050 hddLog(VOS_TRACE_LEVEL_ERROR,
3051 FL("cfg80211_vendor_event_alloc failed"));
3052 return;
3053 }
3054 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3055 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3056 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
3057 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
3058
3059 for (i = 0; i < pData->numOfAps; i++) {
3060 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
3061 "Ssid (%s) "
3062 "Bssid (" MAC_ADDRESS_STR ") "
3063 "Channel (%u) "
3064 "Rssi (%d) "
3065 "RTT (%u) "
3066 "RTT_SD (%u) ",
3067 i,
3068 pData->ap[i].ts,
3069 pData->ap[i].ssid,
3070 MAC_ADDR_ARRAY(pData->ap[i].bssid),
3071 pData->ap[i].channel,
3072 pData->ap[i].rssi,
3073 pData->ap[i].rtt,
3074 pData->ap[i].rtt_sd);
3075 }
3076
3077 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3078 pData->requestId) ||
3079 nla_put_u32(skb,
3080 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3081 pData->numOfAps)) {
3082 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3083 goto fail;
3084 }
3085 if (pData->numOfAps) {
3086 struct nlattr *aps;
3087
3088 aps = nla_nest_start(skb,
3089 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3090 if (!aps)
3091 goto fail;
3092
3093 for (i = 0; i < pData->numOfAps; i++) {
3094 struct nlattr *ap;
3095
3096 ap = nla_nest_start(skb, i + 1);
3097 if (!ap)
3098 goto fail;
3099
3100 if (nla_put_u64(skb,
3101 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3102 pData->ap[i].ts) ||
3103 nla_put(skb,
3104 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3105 sizeof(pData->ap[i].ssid),
3106 pData->ap[i].ssid) ||
3107 nla_put(skb,
3108 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3109 sizeof(pData->ap[i].bssid),
3110 pData->ap[i].bssid) ||
3111 nla_put_u32(skb,
3112 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3113 pData->ap[i].channel) ||
3114 nla_put_s32(skb,
3115 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3116 pData->ap[i].rssi) ||
3117 nla_put_u32(skb,
3118 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3119 pData->ap[i].rtt) ||
3120 nla_put_u32(skb,
3121 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3122 pData->ap[i].rtt_sd))
3123 goto fail;
3124
3125 nla_nest_end(skb, ap);
3126 }
3127 nla_nest_end(skb, aps);
3128
3129 if (nla_put_u8(skb,
3130 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3131 pData->moreData))
3132 goto fail;
3133 }
3134
3135 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303136 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303137 return;
3138
3139fail:
3140 kfree_skb(skb);
3141 return;
3142
3143}
3144static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
3145 void *pMsg)
3146{
3147 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3148 struct sk_buff *skb = NULL;
3149 tANI_U32 i, j;
3150 tpSirWifiSignificantChangeEvent pData =
3151 (tpSirWifiSignificantChangeEvent) pMsg;
3152
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303153 ENTER();
3154
3155 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303156 return;
3157 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303158 if (!pMsg)
3159 {
3160 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3161 return;
3162 }
3163
Dino Mycle6fb96c12014-06-10 11:52:40 +05303164 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303165#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3166 NULL,
3167#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303168 EXTSCAN_EVENT_BUF_SIZE,
3169 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
3170 GFP_KERNEL);
3171
3172 if (!skb) {
3173 hddLog(VOS_TRACE_LEVEL_ERROR,
3174 FL("cfg80211_vendor_event_alloc failed"));
3175 return;
3176 }
3177 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3178 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3179 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
3180 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
3181 pData->numSigRssiBss);
3182 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
3183
3184 for (i = 0; i < pData->numSigRssiBss; i++) {
3185 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
3186 " num RSSI %u ",
3187 i, pData->sigRssiResult[i].bssid,
3188 pData->sigRssiResult[i].channel,
3189 pData->sigRssiResult[i].numRssi);
3190
3191 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
3192
3193 hddLog(VOS_TRACE_LEVEL_INFO,
3194 " [%d]",
Dino Myclec8f3f332014-07-21 16:48:27 +05303195 pData->sigRssiResult[i].rssi[j]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303196
3197 }
3198 }
3199
3200
3201 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3202 pData->requestId) ||
3203 nla_put_u32(skb,
3204 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3205 pData->numSigRssiBss)) {
3206 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3207 goto fail;
3208 }
3209
3210 if (pData->numSigRssiBss) {
3211 struct nlattr *aps;
3212 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3213 if (!aps)
3214 goto fail;
3215 for (i = 0; i < pData->numSigRssiBss; i++) {
3216 struct nlattr *ap;
3217
3218 ap = nla_nest_start(skb, i);
3219 if (!ap)
3220 goto fail;
3221 if (nla_put(skb,
3222 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
3223 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
3224 nla_put_u32(skb,
3225 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
3226 pData->sigRssiResult[i].channel) ||
3227 nla_put_u32(skb,
3228 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
3229 pData->sigRssiResult[i].numRssi) ||
3230 nla_put(skb,
3231 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
3232 sizeof(s32) * pData->sigRssiResult[i].numRssi,
3233 pData->sigRssiResult[i].rssi))
3234 goto fail;
3235 nla_nest_end(skb, ap);
3236 }
3237 nla_nest_end(skb, aps);
3238 if (nla_put_u8(skb,
3239 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3240 pData->moreData))
3241 goto fail;
3242 }
3243 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303244 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303245 return;
3246fail:
3247 kfree_skb(skb);
3248 return;
3249}
3250
3251static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3252 void *pMsg)
3253{
3254 struct sk_buff *skb;
3255 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3256 tpSirWifiFullScanResultEvent pData =
3257 (tpSirWifiFullScanResultEvent) (pMsg);
3258
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303259 ENTER();
3260
3261 if (wlan_hdd_validate_context(pHddCtx)) {
3262 return;
3263 }
3264 if (!pMsg)
3265 {
3266 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303267 return;
3268 }
3269
3270 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303271#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3272 NULL,
3273#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303274 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3275 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3276 GFP_KERNEL);
3277
3278 if (!skb) {
3279 hddLog(VOS_TRACE_LEVEL_ERROR,
3280 FL("cfg80211_vendor_event_alloc failed"));
3281 return;
3282 }
3283
3284 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3285 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3286 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3287 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3288 "Ssid (%s)"
3289 "Bssid (" MAC_ADDRESS_STR ")"
3290 "Channel (%u)"
3291 "Rssi (%d)"
3292 "RTT (%u)"
3293 "RTT_SD (%u)"),
3294 pData->ap.ts,
3295 pData->ap.ssid,
3296 MAC_ADDR_ARRAY(pData->ap.bssid),
3297 pData->ap.channel,
3298 pData->ap.rssi,
3299 pData->ap.rtt,
3300 pData->ap.rtt_sd);
3301 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3302 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3303 pData->requestId) ||
3304 nla_put_u64(skb,
3305 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3306 pData->ap.ts) ||
3307 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3308 sizeof(pData->ap.ssid),
3309 pData->ap.ssid) ||
3310 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3311 WNI_CFG_BSSID_LEN,
3312 pData->ap.bssid) ||
3313 nla_put_u32(skb,
3314 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3315 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303316 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303317 pData->ap.rssi) ||
3318 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3319 pData->ap.rtt) ||
3320 nla_put_u32(skb,
3321 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3322 pData->ap.rtt_sd) ||
3323 nla_put_u16(skb,
3324 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3325 pData->ap.beaconPeriod) ||
3326 nla_put_u16(skb,
3327 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3328 pData->ap.capability) ||
3329 nla_put_u32(skb,
3330 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3331 pData->ieLength))
3332 {
3333 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3334 goto nla_put_failure;
3335 }
3336 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3337 pData->ieLength,
3338 pData->ie))
3339 {
3340 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3341 goto nla_put_failure;
3342 }
3343
3344 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303345 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303346 return;
3347
3348nla_put_failure:
3349 kfree_skb(skb);
3350 return;
3351}
3352
3353static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3354 void *pMsg)
3355{
3356 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3357 struct sk_buff *skb = NULL;
3358 tpSirEXTScanResultsAvailableIndParams pData =
3359 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3360
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303361 ENTER();
3362
3363 if (wlan_hdd_validate_context(pHddCtx)){
3364 return;
3365 }
3366 if (!pMsg)
3367 {
3368 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303369 return;
3370 }
3371
3372 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303373#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3374 NULL,
3375#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303376 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3377 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3378 GFP_KERNEL);
3379
3380 if (!skb) {
3381 hddLog(VOS_TRACE_LEVEL_ERROR,
3382 FL("cfg80211_vendor_event_alloc failed"));
3383 return;
3384 }
3385
3386 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3387 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3388 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3389 pData->numResultsAvailable);
3390 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3391 pData->requestId) ||
3392 nla_put_u32(skb,
3393 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3394 pData->numResultsAvailable)) {
3395 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3396 goto nla_put_failure;
3397 }
3398
3399 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303400 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303401 return;
3402
3403nla_put_failure:
3404 kfree_skb(skb);
3405 return;
3406}
3407
3408static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3409{
3410 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3411 struct sk_buff *skb = NULL;
3412 tpSirEXTScanProgressIndParams pData =
3413 (tpSirEXTScanProgressIndParams) pMsg;
3414
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303415 ENTER();
3416
3417 if (wlan_hdd_validate_context(pHddCtx)){
3418 return;
3419 }
3420 if (!pMsg)
3421 {
3422 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303423 return;
3424 }
3425
3426 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303427#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3428 NULL,
3429#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303430 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3431 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3432 GFP_KERNEL);
3433
3434 if (!skb) {
3435 hddLog(VOS_TRACE_LEVEL_ERROR,
3436 FL("cfg80211_vendor_event_alloc failed"));
3437 return;
3438 }
3439 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3440 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3441 pData->extScanEventType);
3442 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3443 pData->status);
3444
3445 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3446 pData->extScanEventType) ||
3447 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303448 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3449 pData->requestId) ||
3450 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303451 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3452 pData->status)) {
3453 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3454 goto nla_put_failure;
3455 }
3456
3457 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303458 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303459 return;
3460
3461nla_put_failure:
3462 kfree_skb(skb);
3463 return;
3464}
3465
3466void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3467 void *pMsg)
3468{
3469 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3470
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303471 ENTER();
3472
Dino Mycle6fb96c12014-06-10 11:52:40 +05303473 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303474 return;
3475 }
3476
3477 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3478
3479
3480 switch(evType) {
3481 case SIR_HAL_EXTSCAN_START_RSP:
3482 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3483 break;
3484
3485 case SIR_HAL_EXTSCAN_STOP_RSP:
3486 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3487 break;
3488 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3489 /* There is no need to send this response to upper layer
3490 Just log the message */
3491 hddLog(VOS_TRACE_LEVEL_INFO,
3492 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3493 break;
3494 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3495 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3496 break;
3497
3498 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3499 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3500 break;
3501
3502 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
3503 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
3504 break;
3505
3506 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
3507 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
3508 break;
3509 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303510 wlan_hdd_cfg80211_extscan_get_capabilities_rsp(ctx, pMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303511 break;
3512 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3513 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3514 break;
3515 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3516 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3517 break;
3518 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3519 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3520 break;
3521 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3522 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3523 break;
3524 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
3525 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
3526 break;
3527 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3528 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3529 break;
3530 default:
3531 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3532 break;
3533 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303534 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303535}
3536
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303537static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3538 struct wireless_dev *wdev,
3539 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303540{
Dino Myclee8843b32014-07-04 14:21:45 +05303541 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303542 struct net_device *dev = wdev->netdev;
3543 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3544 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3545 struct nlattr
3546 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3547 eHalStatus status;
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303548 struct hdd_ext_scan_context *context;
3549 unsigned long rc;
3550 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303551
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303552 ENTER();
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
3575 /* Parse and fetch request Id */
3576 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3577 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3578 return -EINVAL;
3579 }
3580
Dino Myclee8843b32014-07-04 14:21:45 +05303581 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303582 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
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
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303588 vos_spin_lock_acquire(&hdd_context_lock);
3589 context = &pHddCtx->ext_scan_context;
3590 context->request_id = reqMsg.requestId;
3591 INIT_COMPLETION(context->response_event);
3592 vos_spin_lock_release(&hdd_context_lock);
3593
Dino Myclee8843b32014-07-04 14:21:45 +05303594 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303595 if (!HAL_STATUS_SUCCESS(status)) {
3596 hddLog(VOS_TRACE_LEVEL_ERROR,
3597 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303598 return -EINVAL;
3599 }
Padma, Santhosh Kumara1aa4a32015-06-19 19:00:46 +05303600
3601 rc = wait_for_completion_timeout(&context->response_event,
3602 msecs_to_jiffies(WLAN_WAIT_TIME_EXTSCAN));
3603 if (!rc) {
3604 hddLog(LOGE, FL("Target response timed out"));
3605 return -ETIMEDOUT;
3606 }
3607
3608 ret = wlan_hdd_send_ext_scan_capability(pHddCtx);
3609 if (ret)
3610 hddLog(LOGE, FL("Failed to send ext scan capability to user space"));
3611
3612 return ret;
3613
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303614 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303615 return 0;
3616}
3617
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303618static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3619 struct wireless_dev *wdev,
3620 const void *data, int dataLen)
3621{
3622 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303623
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303624 vos_ssr_protect(__func__);
3625 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3626 vos_ssr_unprotect(__func__);
3627
3628 return ret;
3629}
3630
3631static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3632 struct wireless_dev *wdev,
3633 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303634{
Dino Myclee8843b32014-07-04 14:21:45 +05303635 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303636 struct net_device *dev = wdev->netdev;
3637 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3638 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3639 struct nlattr
3640 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3641 eHalStatus status;
3642
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303643 ENTER();
3644
Dino Mycle6fb96c12014-06-10 11:52:40 +05303645 status = wlan_hdd_validate_context(pHddCtx);
3646 if (0 != status)
3647 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303648 return -EINVAL;
3649 }
Dino Myclee8843b32014-07-04 14:21:45 +05303650 /* check the EXTScan Capability */
3651 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3652 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3653 {
3654 hddLog(VOS_TRACE_LEVEL_ERROR,
3655 FL("EXTScan not enabled/supported by Firmware"));
3656 return -EINVAL;
3657 }
3658
Dino Mycle6fb96c12014-06-10 11:52:40 +05303659 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3660 data, dataLen,
3661 wlan_hdd_extscan_config_policy)) {
3662 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3663 return -EINVAL;
3664 }
3665 /* Parse and fetch request Id */
3666 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3668 return -EINVAL;
3669 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303670
Dino Myclee8843b32014-07-04 14:21:45 +05303671 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303672 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3673
Dino Myclee8843b32014-07-04 14:21:45 +05303674 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303675
Dino Myclee8843b32014-07-04 14:21:45 +05303676 reqMsg.sessionId = pAdapter->sessionId;
3677 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303678
3679 /* Parse and fetch flush parameter */
3680 if (!tb
3681 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3682 {
3683 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3684 goto failed;
3685 }
Dino Myclee8843b32014-07-04 14:21:45 +05303686 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303687 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3688
Dino Myclee8843b32014-07-04 14:21:45 +05303689 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303690
Dino Myclee8843b32014-07-04 14:21:45 +05303691 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303692 if (!HAL_STATUS_SUCCESS(status)) {
3693 hddLog(VOS_TRACE_LEVEL_ERROR,
3694 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303695 return -EINVAL;
3696 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303697 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303698 return 0;
3699
3700failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303701 return -EINVAL;
3702}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303703static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3704 struct wireless_dev *wdev,
3705 const void *data, int dataLen)
3706{
3707 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303708
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303709 vos_ssr_protect(__func__);
3710 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3711 vos_ssr_unprotect(__func__);
3712
3713 return ret;
3714}
3715
3716static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303717 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303718 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303719{
3720 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3721 struct net_device *dev = wdev->netdev;
3722 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3723 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3724 struct nlattr
3725 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3726 struct nlattr
3727 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3728 struct nlattr *apTh;
3729 eHalStatus status;
3730 tANI_U8 i = 0;
3731 int rem;
3732
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303733 ENTER();
3734
Dino Mycle6fb96c12014-06-10 11:52:40 +05303735 status = wlan_hdd_validate_context(pHddCtx);
3736 if (0 != status)
3737 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303738 return -EINVAL;
3739 }
Dino Myclee8843b32014-07-04 14:21:45 +05303740 /* check the EXTScan Capability */
3741 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3742 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3743 {
3744 hddLog(VOS_TRACE_LEVEL_ERROR,
3745 FL("EXTScan not enabled/supported by Firmware"));
3746 return -EINVAL;
3747 }
3748
Dino Mycle6fb96c12014-06-10 11:52:40 +05303749 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3750 data, dataLen,
3751 wlan_hdd_extscan_config_policy)) {
3752 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3753 return -EINVAL;
3754 }
3755
3756 /* Parse and fetch request Id */
3757 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3758 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3759 return -EINVAL;
3760 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303761 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3762 vos_mem_malloc(sizeof(*pReqMsg));
3763 if (!pReqMsg) {
3764 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3765 return -ENOMEM;
3766 }
3767
Dino Myclee8843b32014-07-04 14:21:45 +05303768
Dino Mycle6fb96c12014-06-10 11:52:40 +05303769 pReqMsg->requestId = nla_get_u32(
3770 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3771 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3772
3773 /* Parse and fetch number of APs */
3774 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3775 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3776 goto fail;
3777 }
3778
3779 pReqMsg->sessionId = pAdapter->sessionId;
3780 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3781
3782 pReqMsg->numAp = nla_get_u32(
3783 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3784 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3785
3786 nla_for_each_nested(apTh,
3787 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3788 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3789 nla_data(apTh), nla_len(apTh),
3790 NULL)) {
3791 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3792 goto fail;
3793 }
3794
3795 /* Parse and fetch MAC address */
3796 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3798 goto fail;
3799 }
3800 memcpy(pReqMsg->ap[i].bssid, nla_data(
3801 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3802 sizeof(tSirMacAddr));
3803 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3804
3805 /* Parse and fetch low RSSI */
3806 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3807 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3808 goto fail;
3809 }
3810 pReqMsg->ap[i].low = nla_get_s32(
3811 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3812 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3813
3814 /* Parse and fetch high RSSI */
3815 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3816 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3817 goto fail;
3818 }
3819 pReqMsg->ap[i].high = nla_get_s32(
3820 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3821 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3822 pReqMsg->ap[i].high);
3823
3824 /* Parse and fetch channel */
3825 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3826 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3827 goto fail;
3828 }
3829 pReqMsg->ap[i].channel = nla_get_u32(
3830 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3831 hddLog(VOS_TRACE_LEVEL_INFO,
3832 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3833 i++;
3834 }
3835 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3836 if (!HAL_STATUS_SUCCESS(status)) {
3837 hddLog(VOS_TRACE_LEVEL_ERROR,
3838 FL("sme_SetBssHotlist failed(err=%d)"), status);
3839 vos_mem_free(pReqMsg);
3840 return -EINVAL;
3841 }
3842
Dino Myclee8843b32014-07-04 14:21:45 +05303843 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303844 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303845 return 0;
3846
3847fail:
3848 vos_mem_free(pReqMsg);
3849 return -EINVAL;
3850}
3851
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303852static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3853 struct wireless_dev *wdev,
3854 const void *data, int dataLen)
3855{
3856 int ret = 0;
3857
3858 vos_ssr_protect(__func__);
3859 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3860 dataLen);
3861 vos_ssr_unprotect(__func__);
3862
3863 return ret;
3864}
3865
3866static int __wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303867 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303868 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303869{
3870 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3871 struct net_device *dev = wdev->netdev;
3872 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3873 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3874 struct nlattr
3875 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3876 struct nlattr
3877 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3878 struct nlattr *apTh;
3879 eHalStatus status;
3880 int i = 0;
3881 int rem;
3882
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303883 ENTER();
3884
Dino Mycle6fb96c12014-06-10 11:52:40 +05303885 status = wlan_hdd_validate_context(pHddCtx);
3886 if (0 != status)
3887 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303888 return -EINVAL;
3889 }
Dino Myclee8843b32014-07-04 14:21:45 +05303890 /* check the EXTScan Capability */
3891 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3892 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3893 {
3894 hddLog(VOS_TRACE_LEVEL_ERROR,
3895 FL("EXTScan not enabled/supported by Firmware"));
3896 return -EINVAL;
3897 }
3898
Dino Mycle6fb96c12014-06-10 11:52:40 +05303899 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3900 data, dataLen,
3901 wlan_hdd_extscan_config_policy)) {
3902 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3903 return -EINVAL;
3904 }
3905
3906 /* Parse and fetch request Id */
3907 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3908 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3909 return -EINVAL;
3910 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303911 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303912 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303913 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303914 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3915 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303916 }
3917
Dino Myclee8843b32014-07-04 14:21:45 +05303918
3919
Dino Mycle6fb96c12014-06-10 11:52:40 +05303920 pReqMsg->requestId = nla_get_u32(
3921 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3922 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3923
3924 /* Parse and fetch RSSI sample size */
3925 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3926 {
3927 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3928 goto fail;
3929 }
3930 pReqMsg->rssiSampleSize = nla_get_u32(
3931 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3932 hddLog(VOS_TRACE_LEVEL_INFO,
3933 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3934
3935 /* Parse and fetch lost AP sample size */
3936 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3937 {
3938 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3939 goto fail;
3940 }
3941 pReqMsg->lostApSampleSize = nla_get_u32(
3942 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3943 hddLog(VOS_TRACE_LEVEL_INFO,
3944 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3945 /* Parse and fetch minimum Breaching */
3946 if (!tb
3947 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3948 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3949 goto fail;
3950 }
3951 pReqMsg->minBreaching = nla_get_u32(
3952 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3953 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3954
3955 /* Parse and fetch number of APs */
3956 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3957 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3958 goto fail;
3959 }
3960 pReqMsg->numAp = nla_get_u32(
3961 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3962 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3963
3964 pReqMsg->sessionId = pAdapter->sessionId;
3965 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3966
3967 nla_for_each_nested(apTh,
3968 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3969 if(nla_parse(tb2,
3970 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3971 nla_data(apTh), nla_len(apTh),
3972 NULL)) {
3973 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3974 goto fail;
3975 }
3976
3977 /* Parse and fetch MAC address */
3978 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3979 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3980 goto fail;
3981 }
3982 memcpy(pReqMsg->ap[i].bssid, nla_data(
3983 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3984 sizeof(tSirMacAddr));
3985
3986 /* Parse and fetch low RSSI */
3987 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3988 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3989 goto fail;
3990 }
3991 pReqMsg->ap[i].low = nla_get_s32(
3992 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3993 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3994
3995 /* Parse and fetch high RSSI */
3996 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3997 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3998 goto fail;
3999 }
4000 pReqMsg->ap[i].high = nla_get_s32(
4001 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
4002 hddLog(VOS_TRACE_LEVEL_INFO,
4003 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
4004
4005 /* Parse and fetch channel */
4006 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
4007 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4008 goto fail;
4009 }
4010 pReqMsg->ap[i].channel = nla_get_u32(
4011 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
4012 hddLog(VOS_TRACE_LEVEL_INFO,
4013 FL("Channel (%u)"), pReqMsg->ap[i].channel);
4014 i++;
4015 }
4016
4017 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
4018 if (!HAL_STATUS_SUCCESS(status)) {
4019 hddLog(VOS_TRACE_LEVEL_ERROR,
4020 FL("sme_SetSignificantChange failed(err=%d)"), status);
4021 vos_mem_free(pReqMsg);
4022 return -EINVAL;
4023 }
Dino Myclee8843b32014-07-04 14:21:45 +05304024 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304025 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304026 return 0;
4027
4028fail:
4029 vos_mem_free(pReqMsg);
4030 return -EINVAL;
4031}
4032
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304033static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
4034 struct wireless_dev *wdev,
4035 const void *data, int dataLen)
4036{
4037 int ret = 0;
4038
4039 vos_ssr_protect(__func__);
4040 ret = __wlan_hdd_cfg80211_extscan_set_significant_change(wiphy, wdev, data,
4041 dataLen);
4042 vos_ssr_unprotect(__func__);
4043
4044 return ret;
4045}
4046
4047static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304048 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304049 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304050{
4051 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4052 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
4053 tANI_U8 numChannels = 0;
4054 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304055 tANI_U32 requestId, maxChannels;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304056 tWifiBand wifiBand;
4057 eHalStatus status;
4058 struct sk_buff *replySkb;
4059 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304060 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304061
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304062 ENTER();
4063
Dino Mycle6fb96c12014-06-10 11:52:40 +05304064 status = wlan_hdd_validate_context(pHddCtx);
4065 if (0 != status)
4066 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304067 return -EINVAL;
4068 }
Dino Myclee8843b32014-07-04 14:21:45 +05304069
Dino Mycle6fb96c12014-06-10 11:52:40 +05304070 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4071 data, dataLen,
4072 wlan_hdd_extscan_config_policy)) {
4073 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4074 return -EINVAL;
4075 }
4076
4077 /* Parse and fetch request Id */
4078 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4079 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4080 return -EINVAL;
4081 }
4082 requestId = nla_get_u32(
4083 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4084 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
4085
4086 /* Parse and fetch wifi band */
4087 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
4088 {
4089 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4090 return -EINVAL;
4091 }
4092 wifiBand = nla_get_u32(
4093 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
4094 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
4095
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304096 /* Parse and fetch max channels */
4097 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS])
4098 {
4099 hddLog(LOGE, FL("attr max channels failed"));
4100 return -EINVAL;
4101 }
4102 maxChannels = nla_get_u32(
4103 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_MAX_CHANNELS]);
4104 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max channels %d"), maxChannels);
4105
Dino Mycle6fb96c12014-06-10 11:52:40 +05304106 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
4107 wifiBand, ChannelList,
4108 &numChannels);
4109 if (eHAL_STATUS_SUCCESS != status) {
4110 hddLog(VOS_TRACE_LEVEL_ERROR,
4111 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
4112 return -EINVAL;
4113 }
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304114
4115 numChannels = VOS_MIN(numChannels, maxChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304116 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
Padma, Santhosh Kumar387aa9c2015-06-19 15:39:37 +05304117
Dino Mycle6fb96c12014-06-10 11:52:40 +05304118 for (i = 0; i < numChannels; i++)
4119 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
4120
4121 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
4122 sizeof(u32) * numChannels +
4123 NLMSG_HDRLEN);
4124
4125 if (!replySkb) {
4126 hddLog(VOS_TRACE_LEVEL_ERROR,
4127 FL("valid channels: buffer alloc fail"));
4128 return -EINVAL;
4129 }
4130 if (nla_put_u32(replySkb,
4131 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
4132 numChannels) ||
4133 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
4134 sizeof(u32) * numChannels, ChannelList)) {
4135
4136 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4137 kfree_skb(replySkb);
4138 return -EINVAL;
4139 }
4140
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304141 ret = cfg80211_vendor_cmd_reply(replySkb);
4142
4143 EXIT();
4144 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304145}
4146
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304147static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4148 struct wireless_dev *wdev,
4149 const void *data, int dataLen)
4150{
4151 int ret = 0;
4152
4153 vos_ssr_protect(__func__);
4154 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4155 dataLen);
4156 vos_ssr_unprotect(__func__);
4157
4158 return ret;
4159}
4160
4161static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304162 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304163 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304164{
Dino Myclee8843b32014-07-04 14:21:45 +05304165 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304166 struct net_device *dev = wdev->netdev;
4167 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4168 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4169 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4170 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4171 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4172 struct nlattr *buckets;
4173 struct nlattr *channels;
4174 int rem1;
4175 int rem2;
4176 eHalStatus status;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304177 tANI_U32 j = 0, index = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304178
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304179 ENTER();
4180
Dino Mycle6fb96c12014-06-10 11:52:40 +05304181 status = wlan_hdd_validate_context(pHddCtx);
4182 if (0 != status)
4183 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304184 return -EINVAL;
4185 }
Dino Myclee8843b32014-07-04 14:21:45 +05304186 /* check the EXTScan Capability */
4187 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4188 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4189 {
4190 hddLog(VOS_TRACE_LEVEL_ERROR,
4191 FL("EXTScan not enabled/supported by Firmware"));
4192 return -EINVAL;
4193 }
4194
Dino Mycle6fb96c12014-06-10 11:52:40 +05304195 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4196 data, dataLen,
4197 wlan_hdd_extscan_config_policy)) {
4198 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4199 return -EINVAL;
4200 }
4201
4202 /* Parse and fetch request Id */
4203 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4204 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4205 return -EINVAL;
4206 }
4207
Dino Myclee8843b32014-07-04 14:21:45 +05304208 pReqMsg = (tpSirEXTScanStartReqParams)
4209 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304210 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304211 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4212 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304213 }
4214
4215 pReqMsg->requestId = nla_get_u32(
4216 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4217 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4218
4219 pReqMsg->sessionId = pAdapter->sessionId;
4220 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4221
4222 /* Parse and fetch base period */
4223 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
4224 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4225 goto fail;
4226 }
4227 pReqMsg->basePeriod = nla_get_u32(
4228 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
4229 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4230 pReqMsg->basePeriod);
4231
4232 /* Parse and fetch max AP per scan */
4233 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
4234 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4235 goto fail;
4236 }
4237 pReqMsg->maxAPperScan = nla_get_u32(
4238 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
4239 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4240 pReqMsg->maxAPperScan);
4241
4242 /* Parse and fetch report threshold */
4243 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
4244 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4245 goto fail;
4246 }
4247 pReqMsg->reportThreshold = nla_get_u8(
4248 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
4249 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
4250 pReqMsg->reportThreshold);
4251
4252 /* Parse and fetch number of buckets */
4253 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
4254 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4255 goto fail;
4256 }
4257 pReqMsg->numBuckets = nla_get_u8(
4258 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
4259 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4260 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4261 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4262 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4263 }
4264 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4265 pReqMsg->numBuckets);
4266 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4267 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4268 goto fail;
4269 }
4270
4271 nla_for_each_nested(buckets,
4272 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4273 if(nla_parse(bucket,
4274 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4275 nla_data(buckets), nla_len(buckets), NULL)) { //policy
4276 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4277 goto fail;
4278 }
4279
4280 /* Parse and fetch bucket spec */
4281 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4282 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
4283 goto fail;
4284 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304285
4286 pReqMsg->buckets[index].bucket = nla_get_u8(
4287 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4288
4289 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"),
4290 pReqMsg->buckets[index].bucket);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304291
4292 /* Parse and fetch wifi band */
4293 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4294 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4295 goto fail;
4296 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304297 pReqMsg->buckets[index].band = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304298 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4299 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304300 pReqMsg->buckets[index].band);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304301
4302 /* Parse and fetch period */
4303 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4304 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
4305 goto fail;
4306 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304307 pReqMsg->buckets[index].period = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304308 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4309 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304310 pReqMsg->buckets[index].period);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304311
4312 /* Parse and fetch report events */
4313 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4314 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
4315 goto fail;
4316 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304317 pReqMsg->buckets[index].reportEvents = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304318 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4319 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304320 pReqMsg->buckets[index].reportEvents);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304321
4322 /* Parse and fetch number of channels */
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304323 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS])
4324 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304325 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
4326 goto fail;
4327 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304328 pReqMsg->buckets[index].numChannels = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304329 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4330 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304331 pReqMsg->buckets[index].numChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304332
4333 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4334 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
4335 goto fail;
4336 }
4337
4338 j = 0;
4339 nla_for_each_nested(channels,
4340 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4341 if(nla_parse(channel,
4342 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4343 nla_data(channels), nla_len(channels),
4344 NULL)) { //wlan_hdd_extscan_config_policy here
4345 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4346 goto fail;
4347 }
4348
4349 /* Parse and fetch channel */
4350 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4351 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4352 goto fail;
4353 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304354 pReqMsg->buckets[index].channels[j].channel = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304355 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4356 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304357 pReqMsg->buckets[index].channels[j].channel);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304358
4359 /* Parse and fetch dwell time */
4360 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4361 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
4362 goto fail;
4363 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304364 pReqMsg->buckets[index].channels[j].dwellTimeMs = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304365 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4366 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304367 pReqMsg->buckets[index].channels[j].dwellTimeMs);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304368
4369 /* Parse and fetch channel spec passive */
4370 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4371 hddLog(VOS_TRACE_LEVEL_ERROR,
4372 FL("attr channel spec passive failed"));
4373 goto fail;
4374 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304375 pReqMsg->buckets[index].channels[j].passive = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304376 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4377 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304378 pReqMsg->buckets[index].channels[j].passive);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304379 j++;
4380 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304381 index++;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304382 }
4383 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4384 if (!HAL_STATUS_SUCCESS(status)) {
4385 hddLog(VOS_TRACE_LEVEL_ERROR,
4386 FL("sme_EXTScanStart failed(err=%d)"), status);
4387 vos_mem_free(pReqMsg);
4388 return -EINVAL;
4389 }
4390
Dino Myclee8843b32014-07-04 14:21:45 +05304391 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304392 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304393 return 0;
4394
4395fail:
4396 vos_mem_free(pReqMsg);
4397 return -EINVAL;
4398}
4399
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304400static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4401 struct wireless_dev *wdev,
4402 const void *data, int dataLen)
4403{
4404 int ret = 0;
4405
4406 vos_ssr_protect(__func__);
4407 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4408 vos_ssr_unprotect(__func__);
4409
4410 return ret;
4411}
4412
4413static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304414 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304415 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304416{
Dino Myclee8843b32014-07-04 14:21:45 +05304417 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304418 struct net_device *dev = wdev->netdev;
4419 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4420 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4421 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4422 eHalStatus status;
4423
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304424 ENTER();
4425
Dino Mycle6fb96c12014-06-10 11:52:40 +05304426 status = wlan_hdd_validate_context(pHddCtx);
4427 if (0 != status)
4428 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304429 return -EINVAL;
4430 }
Dino Myclee8843b32014-07-04 14:21:45 +05304431 /* check the EXTScan Capability */
4432 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4433 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4434 {
4435 hddLog(VOS_TRACE_LEVEL_ERROR,
4436 FL("EXTScan not enabled/supported by Firmware"));
4437 return -EINVAL;
4438 }
4439
Dino Mycle6fb96c12014-06-10 11:52:40 +05304440 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4441 data, dataLen,
4442 wlan_hdd_extscan_config_policy)) {
4443 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4444 return -EINVAL;
4445 }
4446
4447 /* Parse and fetch request Id */
4448 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4449 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4450 return -EINVAL;
4451 }
4452
Dino Myclee8843b32014-07-04 14:21:45 +05304453 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304454 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304455 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304456
Dino Myclee8843b32014-07-04 14:21:45 +05304457 reqMsg.sessionId = pAdapter->sessionId;
4458 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304459
Dino Myclee8843b32014-07-04 14:21:45 +05304460 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304461 if (!HAL_STATUS_SUCCESS(status)) {
4462 hddLog(VOS_TRACE_LEVEL_ERROR,
4463 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304464 return -EINVAL;
4465 }
4466
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304467 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304468 return 0;
4469}
4470
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304471static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4472 struct wireless_dev *wdev,
4473 const void *data, int dataLen)
4474{
4475 int ret = 0;
4476
4477 vos_ssr_protect(__func__);
4478 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4479 vos_ssr_unprotect(__func__);
4480
4481 return ret;
4482}
4483
4484static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304485 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304486 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304487{
Dino Myclee8843b32014-07-04 14:21:45 +05304488 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304489 struct net_device *dev = wdev->netdev;
4490 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4491 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4492 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4493 eHalStatus status;
4494
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304495 ENTER();
4496
Dino Mycle6fb96c12014-06-10 11:52:40 +05304497 status = wlan_hdd_validate_context(pHddCtx);
4498 if (0 != status)
4499 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304500 return -EINVAL;
4501 }
Dino Myclee8843b32014-07-04 14:21:45 +05304502 /* check the EXTScan Capability */
4503 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4504 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4505 {
4506 hddLog(VOS_TRACE_LEVEL_ERROR,
4507 FL("EXTScan not enabled/supported by Firmware"));
4508 return -EINVAL;
4509 }
4510
Dino Mycle6fb96c12014-06-10 11:52:40 +05304511 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4512 data, dataLen,
4513 wlan_hdd_extscan_config_policy)) {
4514 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4515 return -EINVAL;
4516 }
4517
4518 /* Parse and fetch request Id */
4519 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4520 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4521 return -EINVAL;
4522 }
4523
Dino Myclee8843b32014-07-04 14:21:45 +05304524 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304525 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304526 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304527
Dino Myclee8843b32014-07-04 14:21:45 +05304528 reqMsg.sessionId = pAdapter->sessionId;
4529 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304530
Dino Myclee8843b32014-07-04 14:21:45 +05304531 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304532 if (!HAL_STATUS_SUCCESS(status)) {
4533 hddLog(VOS_TRACE_LEVEL_ERROR,
4534 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304535 return -EINVAL;
4536 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304537 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304538 return 0;
4539}
4540
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304541static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4542 struct wireless_dev *wdev,
4543 const void *data, int dataLen)
4544{
4545 int ret = 0;
4546
4547 vos_ssr_protect(__func__);
4548 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4549 vos_ssr_unprotect(__func__);
4550
4551 return ret;
4552}
4553
4554static int __wlan_hdd_cfg80211_extscan_reset_significant_change(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304555 struct wiphy *wiphy,
4556 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304557 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304558{
Dino Myclee8843b32014-07-04 14:21:45 +05304559 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304560 struct net_device *dev = wdev->netdev;
4561 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4562 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4563 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4564 eHalStatus status;
4565
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304566 ENTER();
4567
Dino Mycle6fb96c12014-06-10 11:52:40 +05304568 status = wlan_hdd_validate_context(pHddCtx);
4569 if (0 != status)
4570 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304571 return -EINVAL;
4572 }
Dino Myclee8843b32014-07-04 14:21:45 +05304573 /* check the EXTScan Capability */
4574 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4575 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4576 {
4577 hddLog(VOS_TRACE_LEVEL_ERROR,
4578 FL("EXTScan not enabled/supported by Firmware"));
4579 return -EINVAL;
4580 }
4581
Dino Mycle6fb96c12014-06-10 11:52:40 +05304582 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4583 data, dataLen,
4584 wlan_hdd_extscan_config_policy)) {
4585 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4586 return -EINVAL;
4587 }
4588
4589 /* Parse and fetch request Id */
4590 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4591 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4592 return -EINVAL;
4593 }
4594
Dino Mycle6fb96c12014-06-10 11:52:40 +05304595
Dino Myclee8843b32014-07-04 14:21:45 +05304596 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304597 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304598 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304599
Dino Myclee8843b32014-07-04 14:21:45 +05304600 reqMsg.sessionId = pAdapter->sessionId;
4601 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304602
Dino Myclee8843b32014-07-04 14:21:45 +05304603 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304604 if (!HAL_STATUS_SUCCESS(status)) {
4605 hddLog(VOS_TRACE_LEVEL_ERROR,
4606 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304607 return -EINVAL;
4608 }
4609
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304610 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304611 return 0;
4612}
4613
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304614static int wlan_hdd_cfg80211_extscan_reset_significant_change(
4615 struct wiphy *wiphy,
4616 struct wireless_dev *wdev,
4617 const void *data, int dataLen)
4618{
4619 int ret = 0;
4620
4621 vos_ssr_protect(__func__);
4622 ret = __wlan_hdd_cfg80211_extscan_reset_significant_change(wiphy,
4623 wdev, data,
4624 dataLen);
4625 vos_ssr_unprotect(__func__);
4626
4627 return ret;
4628}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304629#endif /* WLAN_FEATURE_EXTSCAN */
4630
Atul Mittal115287b2014-07-08 13:26:33 +05304631/*EXT TDLS*/
4632static const struct nla_policy
4633wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4634{
4635 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4636 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4637 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4638 {.type = NLA_S32 },
4639 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4640 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4641
4642};
4643
4644static const struct nla_policy
4645wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4646{
4647 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4648
4649};
4650
4651static const struct nla_policy
4652wlan_hdd_tdls_config_state_change_policy[
4653 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4654{
4655 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4656 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4657 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304658 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4659 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4660 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304661
4662};
4663
4664static const struct nla_policy
4665wlan_hdd_tdls_config_get_status_policy[
4666 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4667{
4668 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4669 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4670 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304671 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4672 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4673 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304674
4675};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304676
4677static const struct nla_policy
4678wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4679{
4680 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
4681};
4682
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304683static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304684 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304685 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304686 int data_len)
4687{
4688
4689 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4690 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
4691
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304692 ENTER();
4693
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304694 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304695 return -EINVAL;
4696 }
4697 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
Ratheesh S P36dbc932015-08-07 14:28:57 +05304698 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN disabled in ini"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304699 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05304700 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304701 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
Ratheesh S P36dbc932015-08-07 14:28:57 +05304702 hddLog(VOS_TRACE_LEVEL_INFO, FL("MAC_SPOOFED_SCAN not supported by FW"));
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304703 return -ENOTSUPP;
4704 }
4705
4706 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
4707 data, data_len, wlan_hdd_mac_config)) {
4708 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4709 return -EINVAL;
4710 }
4711
4712 /* Parse and fetch mac address */
4713 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
4714 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4715 return -EINVAL;
4716 }
4717
4718 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
4719 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4720 VOS_MAC_ADDR_LAST_3_BYTES);
4721
Siddharth Bhal76972212014-10-15 16:22:51 +05304722 pHddCtx->spoofMacAddr.isEnabled = TRUE;
4723
4724 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304725 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4726 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05304727 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
4728 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
4729 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
4730 {
4731 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
4732 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
4733 VOS_MAC_ADDRESS_LEN);
4734 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304735 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304736
Siddharth Bhal76972212014-10-15 16:22:51 +05304737 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
4738 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304739 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
4740 }
4741
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304742 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304743 return 0;
4744}
4745
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304746static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
4747 struct wireless_dev *wdev,
4748 const void *data,
4749 int data_len)
4750{
4751 int ret = 0;
4752
4753 vos_ssr_protect(__func__);
4754 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
4755 vos_ssr_unprotect(__func__);
4756
4757 return ret;
4758}
4759
4760static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304761 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304762 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304763 int data_len)
4764{
4765 u8 peer[6] = {0};
4766 struct net_device *dev = wdev->netdev;
4767 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4768 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4769 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
4770 eHalStatus ret;
4771 tANI_S32 state;
4772 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304773 tANI_S32 global_operating_class = 0;
4774 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304775 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304776 int retVal;
4777
4778 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304779
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304780 if (!pAdapter) {
4781 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4782 return -EINVAL;
4783 }
4784
Atul Mittal115287b2014-07-08 13:26:33 +05304785 ret = wlan_hdd_validate_context(pHddCtx);
4786 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304787 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304788 return -EINVAL;
4789 }
4790 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304791 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304792 return -ENOTSUPP;
4793 }
4794 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4795 data, data_len,
4796 wlan_hdd_tdls_config_get_status_policy)) {
4797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4798 return -EINVAL;
4799 }
4800
4801 /* Parse and fetch mac address */
4802 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4803 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4804 return -EINVAL;
4805 }
4806
4807 memcpy(peer, nla_data(
4808 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4809 sizeof(peer));
4810 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4811
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05304812 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05304813
Atul Mittal115287b2014-07-08 13:26:33 +05304814 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304815 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05304816 NLMSG_HDRLEN);
4817
4818 if (!skb) {
4819 hddLog(VOS_TRACE_LEVEL_ERROR,
4820 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4821 return -EINVAL;
4822 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304823 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 +05304824 reason,
4825 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304826 global_operating_class,
4827 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05304828 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304829 if (nla_put_s32(skb,
4830 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
4831 state) ||
4832 nla_put_s32(skb,
4833 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
4834 reason) ||
4835 nla_put_s32(skb,
4836 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
4837 global_operating_class) ||
4838 nla_put_s32(skb,
4839 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
4840 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304841
4842 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4843 goto nla_put_failure;
4844 }
4845
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304846 retVal = cfg80211_vendor_cmd_reply(skb);
4847 EXIT();
4848 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05304849
4850nla_put_failure:
4851 kfree_skb(skb);
4852 return -EINVAL;
4853}
4854
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304855static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
4856 struct wireless_dev *wdev,
4857 const void *data,
4858 int data_len)
4859{
4860 int ret = 0;
4861
4862 vos_ssr_protect(__func__);
4863 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
4864 vos_ssr_unprotect(__func__);
4865
4866 return ret;
4867}
4868
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05304869static int wlan_hdd_cfg80211_exttdls_callback(
4870#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
4871 const tANI_U8* mac,
4872#else
4873 tANI_U8* mac,
4874#endif
Atul Mittal115287b2014-07-08 13:26:33 +05304875 tANI_S32 state,
4876 tANI_S32 reason,
4877 void *ctx)
4878{
4879 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05304880 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304881 tANI_S32 global_operating_class = 0;
4882 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304883 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05304884
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304885 ENTER();
4886
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304887 if (!pAdapter) {
4888 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4889 return -EINVAL;
4890 }
4891
4892 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05304893 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304894 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304895 return -EINVAL;
4896 }
4897
4898 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304899 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304900 return -ENOTSUPP;
4901 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304902 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
4903#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4904 NULL,
4905#endif
Atul Mittal115287b2014-07-08 13:26:33 +05304906 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4907 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4908 GFP_KERNEL);
4909
4910 if (!skb) {
4911 hddLog(VOS_TRACE_LEVEL_ERROR,
4912 FL("cfg80211_vendor_event_alloc failed"));
4913 return -EINVAL;
4914 }
4915 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304916 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
4917 reason,
4918 state,
4919 global_operating_class,
4920 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05304921 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4922 MAC_ADDR_ARRAY(mac));
4923
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304924 if (nla_put(skb,
4925 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4926 VOS_MAC_ADDR_SIZE, mac) ||
4927 nla_put_s32(skb,
4928 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
4929 state) ||
4930 nla_put_s32(skb,
4931 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
4932 reason) ||
4933 nla_put_s32(skb,
4934 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
4935 channel) ||
4936 nla_put_s32(skb,
4937 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
4938 global_operating_class)
4939 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05304940 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4941 goto nla_put_failure;
4942 }
4943
4944 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304945 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05304946 return (0);
4947
4948nla_put_failure:
4949 kfree_skb(skb);
4950 return -EINVAL;
4951}
4952
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304953static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304954 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304955 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304956 int data_len)
4957{
4958 u8 peer[6] = {0};
4959 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304960 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4961 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4962 eHalStatus status;
4963 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304964 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304965 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304966
4967 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304968
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304969 if (!dev) {
4970 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4971 return -EINVAL;
4972 }
4973
4974 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4975 if (!pAdapter) {
4976 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4977 return -EINVAL;
4978 }
4979
Atul Mittal115287b2014-07-08 13:26:33 +05304980 status = wlan_hdd_validate_context(pHddCtx);
4981 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304982 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304983 return -EINVAL;
4984 }
4985 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304986 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304987 return -ENOTSUPP;
4988 }
4989 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4990 data, data_len,
4991 wlan_hdd_tdls_config_enable_policy)) {
4992 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4993 return -EINVAL;
4994 }
4995
4996 /* Parse and fetch mac address */
4997 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4998 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4999 return -EINVAL;
5000 }
5001
5002 memcpy(peer, nla_data(
5003 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
5004 sizeof(peer));
5005 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5006
5007 /* Parse and fetch channel */
5008 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
5009 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
5010 return -EINVAL;
5011 }
5012 pReqMsg.channel = nla_get_s32(
5013 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
5014 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
5015
5016 /* Parse and fetch global operating class */
5017 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
5018 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
5019 return -EINVAL;
5020 }
5021 pReqMsg.global_operating_class = nla_get_s32(
5022 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
5023 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
5024 pReqMsg.global_operating_class);
5025
5026 /* Parse and fetch latency ms */
5027 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
5028 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
5029 return -EINVAL;
5030 }
5031 pReqMsg.max_latency_ms = nla_get_s32(
5032 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
5033 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
5034 pReqMsg.max_latency_ms);
5035
5036 /* Parse and fetch required bandwidth kbps */
5037 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
5038 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
5039 return -EINVAL;
5040 }
5041
5042 pReqMsg.min_bandwidth_kbps = nla_get_s32(
5043 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
5044 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
5045 pReqMsg.min_bandwidth_kbps);
5046
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305047 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05305048 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05305049 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305050 wlan_hdd_cfg80211_exttdls_callback);
5051
5052 EXIT();
5053 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305054}
5055
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305056static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
5057 struct wireless_dev *wdev,
5058 const void *data,
5059 int data_len)
5060{
5061 int ret = 0;
5062
5063 vos_ssr_protect(__func__);
5064 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
5065 vos_ssr_unprotect(__func__);
5066
5067 return ret;
5068}
5069
5070static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05305071 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305072 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05305073 int data_len)
5074{
5075 u8 peer[6] = {0};
5076 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05305077 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5078 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
5079 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305080 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305081 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305082
5083 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05305084
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05305085 if (!dev) {
5086 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
5087 return -EINVAL;
5088 }
5089
5090 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5091 if (!pAdapter) {
5092 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
5093 return -EINVAL;
5094 }
5095
Atul Mittal115287b2014-07-08 13:26:33 +05305096 status = wlan_hdd_validate_context(pHddCtx);
5097 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305098 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05305099 return -EINVAL;
5100 }
5101 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05305102 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05305103 return -ENOTSUPP;
5104 }
5105 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
5106 data, data_len,
5107 wlan_hdd_tdls_config_disable_policy)) {
5108 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5109 return -EINVAL;
5110 }
5111 /* Parse and fetch mac address */
5112 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
5113 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
5114 return -EINVAL;
5115 }
5116
5117 memcpy(peer, nla_data(
5118 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
5119 sizeof(peer));
5120 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
5121
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305122 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
5123
5124 EXIT();
5125 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05305126}
5127
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305128static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
5129 struct wireless_dev *wdev,
5130 const void *data,
5131 int data_len)
5132{
5133 int ret = 0;
5134
5135 vos_ssr_protect(__func__);
5136 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
5137 vos_ssr_unprotect(__func__);
5138
5139 return ret;
5140}
5141
Dasari Srinivas7875a302014-09-26 17:50:57 +05305142static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305143__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305144 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305145 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305146{
5147 struct net_device *dev = wdev->netdev;
5148 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5149 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5150 struct sk_buff *skb = NULL;
5151 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305152 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305153
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305154 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305155
5156 ret = wlan_hdd_validate_context(pHddCtx);
5157 if (0 != ret)
5158 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305159 return ret;
5160 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305161 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5162 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5163 fset |= WIFI_FEATURE_INFRA;
5164 }
5165
5166 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5167 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5168 fset |= WIFI_FEATURE_INFRA_5G;
5169 }
5170
5171#ifdef WLAN_FEATURE_P2P
5172 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5173 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5174 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5175 fset |= WIFI_FEATURE_P2P;
5176 }
5177#endif
5178
5179 /* Soft-AP is supported currently by default */
5180 fset |= WIFI_FEATURE_SOFT_AP;
5181
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305182 /* HOTSPOT is a supplicant feature, enable it by default */
5183 fset |= WIFI_FEATURE_HOTSPOT;
5184
Dasari Srinivas7875a302014-09-26 17:50:57 +05305185#ifdef WLAN_FEATURE_EXTSCAN
5186 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
5187 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
5188 hddLog(LOG1, FL("EXTScan is supported by firmware"));
5189 fset |= WIFI_FEATURE_EXTSCAN;
5190 }
5191#endif
5192
Dasari Srinivas7875a302014-09-26 17:50:57 +05305193 if (sme_IsFeatureSupportedByFW(NAN)) {
5194 hddLog(LOG1, FL("NAN is supported by firmware"));
5195 fset |= WIFI_FEATURE_NAN;
5196 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305197
5198 /* D2D RTT is not supported currently by default */
5199 if (sme_IsFeatureSupportedByFW(RTT)) {
5200 hddLog(LOG1, FL("RTT is supported by firmware"));
5201 fset |= WIFI_FEATURE_D2AP_RTT;
5202 }
5203
5204#ifdef FEATURE_WLAN_BATCH_SCAN
5205 if (fset & WIFI_FEATURE_EXTSCAN) {
5206 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5207 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5208 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5209 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5210 fset |= WIFI_FEATURE_BATCH_SCAN;
5211 }
5212#endif
5213
5214#ifdef FEATURE_WLAN_SCAN_PNO
5215 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5216 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5217 hddLog(LOG1, FL("PNO is supported by firmware"));
5218 fset |= WIFI_FEATURE_PNO;
5219 }
5220#endif
5221
5222 /* STA+STA is supported currently by default */
5223 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5224
5225#ifdef FEATURE_WLAN_TDLS
5226 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5227 sme_IsFeatureSupportedByFW(TDLS)) {
5228 hddLog(LOG1, FL("TDLS is supported by firmware"));
5229 fset |= WIFI_FEATURE_TDLS;
5230 }
5231
5232 /* TDLS_OFFCHANNEL is not supported currently by default */
5233#endif
5234
5235#ifdef WLAN_AP_STA_CONCURRENCY
5236 /* AP+STA concurrency is supported currently by default */
5237 fset |= WIFI_FEATURE_AP_STA;
5238#endif
5239
Mukul Sharma5add0532015-08-17 15:57:47 +05305240#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5241 fset |= WIFI_FEATURE_LINK_LAYER_STATS;
5242 hddLog(LOG1, FL("Link layer stats is supported by driver"));
5243#endif
5244
Dasari Srinivas7875a302014-09-26 17:50:57 +05305245 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5246 NLMSG_HDRLEN);
5247
5248 if (!skb) {
5249 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5250 return -EINVAL;
5251 }
5252 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5253
5254 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5255 hddLog(LOGE, FL("nla put fail"));
5256 goto nla_put_failure;
5257 }
5258
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305259 ret = cfg80211_vendor_cmd_reply(skb);
5260 EXIT();
5261 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305262
5263nla_put_failure:
5264 kfree_skb(skb);
5265 return -EINVAL;
5266}
5267
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305268static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305269wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5270 struct wireless_dev *wdev,
5271 const void *data, int data_len)
5272{
5273 int ret = 0;
5274
5275 vos_ssr_protect(__func__);
5276 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5277 vos_ssr_unprotect(__func__);
5278
5279 return ret;
5280}
5281
5282static int
5283__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305284 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305285 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305286{
5287 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5288 uint8_t i, feature_sets, max_feature_sets;
5289 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5290 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305291 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5292 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305293
5294 ENTER();
5295
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305296 ret = wlan_hdd_validate_context(pHddCtx);
5297 if (0 != ret)
5298 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305299 return ret;
5300 }
5301
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305302 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5303 data, data_len, NULL)) {
5304 hddLog(LOGE, FL("Invalid ATTR"));
5305 return -EINVAL;
5306 }
5307
5308 /* Parse and fetch max feature set */
5309 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5310 hddLog(LOGE, FL("Attr max feature set size failed"));
5311 return -EINVAL;
5312 }
5313 max_feature_sets = nla_get_u32(
5314 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5315 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5316
5317 /* Fill feature combination matrix */
5318 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305319 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5320 WIFI_FEATURE_P2P;
5321
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305322 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5323 WIFI_FEATURE_SOFT_AP;
5324
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305325 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5326 WIFI_FEATURE_SOFT_AP;
5327
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305328 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5329 WIFI_FEATURE_SOFT_AP |
5330 WIFI_FEATURE_P2P;
5331
5332 /* Add more feature combinations here */
5333
5334 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5335 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5336 hddLog(LOG1, "Feature set matrix");
5337 for (i = 0; i < feature_sets; i++)
5338 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5339
5340 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5341 sizeof(u32) * feature_sets +
5342 NLMSG_HDRLEN);
5343
5344 if (reply_skb) {
5345 if (nla_put_u32(reply_skb,
5346 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5347 feature_sets) ||
5348 nla_put(reply_skb,
5349 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5350 sizeof(u32) * feature_sets, feature_set_matrix)) {
5351 hddLog(LOGE, FL("nla put fail"));
5352 kfree_skb(reply_skb);
5353 return -EINVAL;
5354 }
5355
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305356 ret = cfg80211_vendor_cmd_reply(reply_skb);
5357 EXIT();
5358 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305359 }
5360 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5361 return -ENOMEM;
5362
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305363}
5364
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305365static int
5366wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5367 struct wireless_dev *wdev,
5368 const void *data, int data_len)
5369{
5370 int ret = 0;
5371
5372 vos_ssr_protect(__func__);
5373 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5374 data_len);
5375 vos_ssr_unprotect(__func__);
5376
5377 return ret;
5378}
5379
Agarwal Ashish738843c2014-09-25 12:27:56 +05305380static const struct nla_policy
5381wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5382 +1] =
5383{
5384 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5385};
5386
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305387static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305388 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305389 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305390 int data_len)
5391{
5392 struct net_device *dev = wdev->netdev;
5393 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5394 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5395 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5396 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5397 eHalStatus status;
5398 u32 dfsFlag = 0;
5399
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305400 ENTER();
5401
Agarwal Ashish738843c2014-09-25 12:27:56 +05305402 status = wlan_hdd_validate_context(pHddCtx);
5403 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305404 return -EINVAL;
5405 }
5406 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5407 data, data_len,
5408 wlan_hdd_set_no_dfs_flag_config_policy)) {
5409 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5410 return -EINVAL;
5411 }
5412
5413 /* Parse and fetch required bandwidth kbps */
5414 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5415 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5416 return -EINVAL;
5417 }
5418
5419 dfsFlag = nla_get_u32(
5420 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5421 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5422 dfsFlag);
5423
5424 pHddCtx->disable_dfs_flag = dfsFlag;
5425
5426 sme_disable_dfs_channel(hHal, dfsFlag);
5427 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305428
5429 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305430 return 0;
5431}
Atul Mittal115287b2014-07-08 13:26:33 +05305432
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305433static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
5434 struct wireless_dev *wdev,
5435 const void *data,
5436 int data_len)
5437{
5438 int ret = 0;
5439
5440 vos_ssr_protect(__func__);
5441 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
5442 vos_ssr_unprotect(__func__);
5443
5444 return ret;
5445
5446}
5447
Mukul Sharma2a271632014-10-13 14:59:01 +05305448const struct
5449nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
5450{
5451 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
5452 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
5453};
5454
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305455static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05305456 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05305457{
5458
5459 u8 bssid[6] = {0};
5460 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5461 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5462 eHalStatus status = eHAL_STATUS_SUCCESS;
5463 v_U32_t isFwrRoamEnabled = FALSE;
5464 int ret;
5465
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305466 ENTER();
5467
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305468 ret = wlan_hdd_validate_context(pHddCtx);
5469 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305470 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05305471 }
5472
5473 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
5474 data, data_len,
5475 qca_wlan_vendor_attr);
5476 if (ret){
5477 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5478 return -EINVAL;
5479 }
5480
5481 /* Parse and fetch Enable flag */
5482 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
5483 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
5484 return -EINVAL;
5485 }
5486
5487 isFwrRoamEnabled = nla_get_u32(
5488 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5489
5490 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5491
5492 /* Parse and fetch bssid */
5493 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5494 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5495 return -EINVAL;
5496 }
5497
5498 memcpy(bssid, nla_data(
5499 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
5500 sizeof(bssid));
5501 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
5502
5503 //Update roaming
5504 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305505 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05305506 return status;
5507}
5508
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305509static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
5510 struct wireless_dev *wdev, const void *data, int data_len)
5511{
5512 int ret = 0;
5513
5514 vos_ssr_protect(__func__);
5515 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
5516 vos_ssr_unprotect(__func__);
5517
5518 return ret;
5519}
5520
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305521/**
5522 * __wlan_hdd_cfg80211_setband() - set band
5523 * @wiphy: Pointer to wireless phy
5524 * @wdev: Pointer to wireless device
5525 * @data: Pointer to data
5526 * @data_len: Data length
5527 *
5528 * Return: 0 on success, negative errno on failure
5529 */
5530static int
5531__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
5532 struct wireless_dev *wdev,
5533 const void *data,
5534 int data_len)
5535{
5536 struct net_device *dev = wdev->netdev;
5537 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5538 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5539 int ret;
5540 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
5541 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
5542
5543 ENTER();
5544
5545 ret = wlan_hdd_validate_context(hdd_ctx);
5546 if (0 != ret) {
5547 hddLog(LOGE, FL("HDD context is not valid"));
5548 return ret;
5549 }
5550
5551 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
5552 policy)) {
5553 hddLog(LOGE, FL("Invalid ATTR"));
5554 return -EINVAL;
5555 }
5556
5557 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
5558 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
5559 return -EINVAL;
5560 }
5561
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05305562 hdd_ctx->isSetBandByNL = TRUE;
5563 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305564 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05305565 hdd_ctx->isSetBandByNL = FALSE;
5566
5567 EXIT();
5568 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305569}
5570
5571/**
5572 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
5573 * @wiphy: wiphy structure pointer
5574 * @wdev: Wireless device structure pointer
5575 * @data: Pointer to the data received
5576 * @data_len: Length of @data
5577 *
5578 * Return: 0 on success; errno on failure
5579 */
5580static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
5581 struct wireless_dev *wdev,
5582 const void *data,
5583 int data_len)
5584{
5585 int ret = 0;
5586
5587 vos_ssr_protect(__func__);
5588 ret = __wlan_hdd_cfg80211_setband(wiphy,
5589 wdev, data, data_len);
5590 vos_ssr_unprotect(__func__);
5591
5592 return ret;
5593}
5594
Sunil Duttc69bccb2014-05-26 21:30:20 +05305595const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
5596{
Mukul Sharma2a271632014-10-13 14:59:01 +05305597 {
5598 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5599 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
5600 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5601 WIPHY_VENDOR_CMD_NEED_NETDEV |
5602 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305603 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05305604 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05305605
5606 {
5607 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5608 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
5609 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5610 WIPHY_VENDOR_CMD_NEED_NETDEV |
5611 WIPHY_VENDOR_CMD_NEED_RUNNING,
5612 .doit = wlan_hdd_cfg80211_nan_request
5613 },
5614
Sunil Duttc69bccb2014-05-26 21:30:20 +05305615#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5616 {
5617 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5618 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
5619 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5620 WIPHY_VENDOR_CMD_NEED_NETDEV |
5621 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305622 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05305623 },
5624
5625 {
5626 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5627 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
5628 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5629 WIPHY_VENDOR_CMD_NEED_NETDEV |
5630 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305631 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05305632 },
5633
5634 {
5635 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5636 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
5637 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5638 WIPHY_VENDOR_CMD_NEED_NETDEV |
5639 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305640 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05305641 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305642#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305643#ifdef WLAN_FEATURE_EXTSCAN
5644 {
5645 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5646 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
5647 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5648 WIPHY_VENDOR_CMD_NEED_NETDEV |
5649 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305650 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05305651 },
5652 {
5653 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5654 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
5655 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5656 WIPHY_VENDOR_CMD_NEED_NETDEV |
5657 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305658 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05305659 },
5660 {
5661 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5662 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
5663 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5664 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305665 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05305666 },
5667 {
5668 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5669 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
5670 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5671 WIPHY_VENDOR_CMD_NEED_NETDEV |
5672 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305673 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05305674 },
5675 {
5676 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5677 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
5678 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5679 WIPHY_VENDOR_CMD_NEED_NETDEV |
5680 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305681 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05305682 },
5683 {
5684 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5685 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
5686 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5687 WIPHY_VENDOR_CMD_NEED_NETDEV |
5688 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305689 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305690 },
5691 {
5692 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5693 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
5694 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5695 WIPHY_VENDOR_CMD_NEED_NETDEV |
5696 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305697 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305698 },
5699 {
5700 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5701 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
5702 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5703 WIPHY_VENDOR_CMD_NEED_NETDEV |
5704 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305705 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305706 },
5707 {
5708 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5709 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
5710 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5711 WIPHY_VENDOR_CMD_NEED_NETDEV |
5712 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305713 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305714 },
5715#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305716/*EXT TDLS*/
5717 {
5718 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5719 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
5720 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5721 WIPHY_VENDOR_CMD_NEED_NETDEV |
5722 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305723 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05305724 },
5725 {
5726 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5727 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
5728 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5729 WIPHY_VENDOR_CMD_NEED_NETDEV |
5730 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305731 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05305732 },
5733 {
5734 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5735 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
5736 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5737 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305738 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05305739 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05305740 {
5741 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5742 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
5743 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5744 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305745 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05305746 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05305747 {
5748 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5749 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
5750 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5751 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305752 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05305753 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305754 {
5755 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5756 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
5757 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5758 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305759 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305760 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305761 {
5762 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5763 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
5764 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5765 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305766 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305767 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305768 {
5769 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5770 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
5771 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5772 WIPHY_VENDOR_CMD_NEED_NETDEV |
5773 WIPHY_VENDOR_CMD_NEED_RUNNING,
5774 .doit = wlan_hdd_cfg80211_setband
5775 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05305776};
5777
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005778/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05305779static const
5780struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005781{
5782#ifdef FEATURE_WLAN_CH_AVOID
5783 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05305784 .vendor_id = QCA_NL80211_VENDOR_ID,
5785 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005786 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305787#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
5788#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5789 {
5790 /* Index = 1*/
5791 .vendor_id = QCA_NL80211_VENDOR_ID,
5792 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
5793 },
5794 {
5795 /* Index = 2*/
5796 .vendor_id = QCA_NL80211_VENDOR_ID,
5797 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
5798 },
5799 {
5800 /* Index = 3*/
5801 .vendor_id = QCA_NL80211_VENDOR_ID,
5802 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
5803 },
5804 {
5805 /* Index = 4*/
5806 .vendor_id = QCA_NL80211_VENDOR_ID,
5807 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
5808 },
5809 {
5810 /* Index = 5*/
5811 .vendor_id = QCA_NL80211_VENDOR_ID,
5812 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
5813 },
5814 {
5815 /* Index = 6*/
5816 .vendor_id = QCA_NL80211_VENDOR_ID,
5817 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
5818 },
5819#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305820#ifdef WLAN_FEATURE_EXTSCAN
5821 {
5822 .vendor_id = QCA_NL80211_VENDOR_ID,
5823 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
5824 },
5825 {
5826 .vendor_id = QCA_NL80211_VENDOR_ID,
5827 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
5828 },
5829 {
5830 .vendor_id = QCA_NL80211_VENDOR_ID,
5831 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
5832 },
5833 {
5834 .vendor_id = QCA_NL80211_VENDOR_ID,
5835 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
5836 },
5837 {
5838 .vendor_id = QCA_NL80211_VENDOR_ID,
5839 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
5840 },
5841 {
5842 .vendor_id = QCA_NL80211_VENDOR_ID,
5843 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
5844 },
5845 {
5846 .vendor_id = QCA_NL80211_VENDOR_ID,
5847 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
5848 },
5849 {
5850 .vendor_id = QCA_NL80211_VENDOR_ID,
5851 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
5852 },
5853 {
5854 .vendor_id = QCA_NL80211_VENDOR_ID,
5855 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
5856 },
5857 {
5858 .vendor_id = QCA_NL80211_VENDOR_ID,
5859 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
5860 },
5861 {
5862 .vendor_id = QCA_NL80211_VENDOR_ID,
5863 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
5864 },
5865 {
5866 .vendor_id = QCA_NL80211_VENDOR_ID,
5867 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
5868 },
5869 {
5870 .vendor_id = QCA_NL80211_VENDOR_ID,
5871 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
5872 },
5873#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305874/*EXT TDLS*/
5875 {
5876 .vendor_id = QCA_NL80211_VENDOR_ID,
5877 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
5878 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05305879
5880 {
5881 .vendor_id = QCA_NL80211_VENDOR_ID,
5882 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
5883 },
5884
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005885};
5886
Jeff Johnson295189b2012-06-20 16:38:30 -07005887/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305888 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305889 * This function is called by hdd_wlan_startup()
5890 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305891 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07005892 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305893struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07005894{
5895 struct wiphy *wiphy;
5896 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305897 /*
5898 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07005899 */
5900 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
5901
5902 if (!wiphy)
5903 {
5904 /* Print error and jump into err label and free the memory */
5905 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
5906 return NULL;
5907 }
5908
Sunil Duttc69bccb2014-05-26 21:30:20 +05305909
Jeff Johnson295189b2012-06-20 16:38:30 -07005910 return wiphy;
5911}
5912
5913/*
5914 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305915 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07005916 * private ioctl to change the band value
5917 */
5918int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
5919{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305920 int i, j;
5921 eNVChannelEnabledType channelEnabledState;
5922
Jeff Johnsone7245742012-09-05 17:12:55 -07005923 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305924
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305925 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005926 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305927
5928 if (NULL == wiphy->bands[i])
5929 {
5930 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5931 __func__, i);
5932 continue;
5933 }
5934
5935 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5936 {
5937 struct ieee80211_supported_band *band = wiphy->bands[i];
5938
5939 channelEnabledState = vos_nv_getChannelEnabledState(
5940 band->channels[j].hw_value);
5941
5942 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
5943 {
Abhishek Singh678227a2014-11-04 10:52:38 +05305944 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305945 continue;
5946 }
5947 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
5948 {
5949 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5950 continue;
5951 }
5952
5953 if (NV_CHANNEL_DISABLE == channelEnabledState ||
5954 NV_CHANNEL_INVALID == channelEnabledState)
5955 {
5956 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5957 }
5958 else if (NV_CHANNEL_DFS == channelEnabledState)
5959 {
5960 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5961 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
5962 }
5963 else
5964 {
5965 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
5966 |IEEE80211_CHAN_RADAR);
5967 }
5968 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005969 }
5970 return 0;
5971}
5972/*
5973 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305974 * This function is called by hdd_wlan_startup()
5975 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07005976 * This function is used to initialize and register wiphy structure.
5977 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305978int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005979 struct wiphy *wiphy,
5980 hdd_config_t *pCfg
5981 )
5982{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305983 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305984 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5985
Jeff Johnsone7245742012-09-05 17:12:55 -07005986 ENTER();
5987
Jeff Johnson295189b2012-06-20 16:38:30 -07005988 /* Now bind the underlying wlan device with wiphy */
5989 set_wiphy_dev(wiphy, dev);
5990
5991 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005992
Kiet Lam6c583332013-10-14 05:37:09 +05305993#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07005994 /* the flag for the other case would be initialzed in
5995 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07005996 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05305997#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005998
Amar Singhalfddc28c2013-09-05 13:03:40 -07005999 /* This will disable updating of NL channels from passive to
6000 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306001#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
6002 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
6003#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07006004 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306005#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07006006
Amar Singhala49cbc52013-10-08 18:37:44 -07006007
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006008#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07006009 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
6010 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
6011 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07006012 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05306013#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
6014 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
6015#else
6016 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
6017#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006018#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07006019
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006020#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006021 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08006022#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006023 || pCfg->isFastRoamIniFeatureEnabled
6024#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08006025#ifdef FEATURE_WLAN_ESE
6026 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07006027#endif
6028 )
6029 {
6030 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
6031 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08006032#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006033#ifdef FEATURE_WLAN_TDLS
6034 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
6035 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
6036#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05306037#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05306038 if (pCfg->configPNOScanSupport)
6039 {
6040 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
6041 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
6042 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
6043 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
6044 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05306045#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08006046
Abhishek Singh10d85972015-04-17 10:27:23 +05306047#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6048 wiphy->features |= NL80211_FEATURE_HT_IBSS;
6049#endif
6050
Amar Singhalfddc28c2013-09-05 13:03:40 -07006051#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07006052 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
6053 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07006054 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07006055 driver need to determine what to do with both
6056 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07006057
6058 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07006059#else
6060 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07006061#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006062
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306063 wiphy->max_scan_ssids = MAX_SCAN_SSID;
6064
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05306065 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07006066
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05306067 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
6068
Jeff Johnson295189b2012-06-20 16:38:30 -07006069 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05306070 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
6071 | BIT(NL80211_IFTYPE_ADHOC)
6072 | BIT(NL80211_IFTYPE_P2P_CLIENT)
6073 | BIT(NL80211_IFTYPE_P2P_GO)
6074 | BIT(NL80211_IFTYPE_AP);
6075
6076 if (VOS_MONITOR_MODE == hdd_get_conparam())
6077 {
6078 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
6079 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006080
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306081 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006082 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306083#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
6084 if( pCfg->enableMCC )
6085 {
6086 /* Currently, supports up to two channels */
6087 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006088
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306089 if( !pCfg->allowMCCGODiffBI )
6090 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006091
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306092 }
6093 wiphy->iface_combinations = &wlan_hdd_iface_combination;
6094 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006095#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05306096 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08006097
Jeff Johnson295189b2012-06-20 16:38:30 -07006098 /* Before registering we need to update the ht capabilitied based
6099 * on ini values*/
6100 if( !pCfg->ShortGI20MhzEnable )
6101 {
6102 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6103 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6104 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
6105 }
6106
6107 if( !pCfg->ShortGI40MhzEnable )
6108 {
6109 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
6110 }
6111
6112 if( !pCfg->nChannelBondingMode5GHz )
6113 {
6114 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6115 }
6116
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306117 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05306118 if (true == hdd_is_5g_supported(pHddCtx))
6119 {
6120 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
6121 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306122
6123 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
6124 {
6125
6126 if (NULL == wiphy->bands[i])
6127 {
Ratheesh S P36dbc932015-08-07 14:28:57 +05306128 hddLog(VOS_TRACE_LEVEL_INFO,"%s: wiphy->bands[i] is NULL, i = %d",
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05306129 __func__, i);
6130 continue;
6131 }
6132
6133 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
6134 {
6135 struct ieee80211_supported_band *band = wiphy->bands[i];
6136
6137 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
6138 {
6139 // Enable social channels for P2P
6140 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
6141 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
6142 else
6143 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6144 continue;
6145 }
6146 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
6147 {
6148 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6149 continue;
6150 }
6151 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006152 }
6153 /*Initialise the supported cipher suite details*/
6154 wiphy->cipher_suites = hdd_cipher_suites;
6155 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
6156
6157 /*signal strength in mBm (100*dBm) */
6158 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
6159
6160#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05306161 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07006162#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006163
Sunil Duttc69bccb2014-05-26 21:30:20 +05306164 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
6165 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006166 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
6167 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
6168
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306169 EXIT();
6170 return 0;
6171}
6172
6173/* In this function we are registering wiphy. */
6174int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
6175{
6176 ENTER();
6177 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006178 if (0 > wiphy_register(wiphy))
6179 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306180 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07006181 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
6182 return -EIO;
6183 }
6184
6185 EXIT();
6186 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306187}
Jeff Johnson295189b2012-06-20 16:38:30 -07006188
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306189/* In this function we are updating channel list when,
6190 regulatory domain is FCC and country code is US.
6191 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
6192 As per FCC smart phone is not a indoor device.
6193 GO should not opeate on indoor channels */
6194void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
6195{
6196 int j;
6197 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6198 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
6199 //Default counrtycode from NV at the time of wiphy initialization.
6200 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
6201 &defaultCountryCode[0]))
6202 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006203 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306204 }
6205 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
6206 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306207 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
6208 {
6209 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
6210 return;
6211 }
6212 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
6213 {
6214 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
6215 // Mark UNII -1 band channel as passive
6216 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
6217 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
6218 }
6219 }
6220}
6221
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306222/* This function registers for all frame which supplicant is interested in */
6223void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006224{
Jeff Johnson295189b2012-06-20 16:38:30 -07006225 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6226 /* Register for all P2P action, public action etc frames */
6227 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6228
Jeff Johnsone7245742012-09-05 17:12:55 -07006229 ENTER();
6230
Jeff Johnson295189b2012-06-20 16:38:30 -07006231 /* Right now we are registering these frame when driver is getting
6232 initialized. Once we will move to 2.6.37 kernel, in which we have
6233 frame register ops, we will move this code as a part of that */
6234 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306235 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006236 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6237
6238 /* GAS Initial Response */
6239 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6240 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306241
Jeff Johnson295189b2012-06-20 16:38:30 -07006242 /* GAS Comeback Request */
6243 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6244 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6245
6246 /* GAS Comeback Response */
6247 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6248 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6249
6250 /* P2P Public Action */
6251 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306252 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006253 P2P_PUBLIC_ACTION_FRAME_SIZE );
6254
6255 /* P2P Action */
6256 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6257 (v_U8_t*)P2P_ACTION_FRAME,
6258 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07006259
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05306260 /* WNM BSS Transition Request frame */
6261 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6262 (v_U8_t*)WNM_BSS_ACTION_FRAME,
6263 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006264
6265 /* WNM-Notification */
6266 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6267 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6268 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006269}
6270
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306271void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006272{
Jeff Johnson295189b2012-06-20 16:38:30 -07006273 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6274 /* Register for all P2P action, public action etc frames */
6275 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6276
Jeff Johnsone7245742012-09-05 17:12:55 -07006277 ENTER();
6278
Jeff Johnson295189b2012-06-20 16:38:30 -07006279 /* Right now we are registering these frame when driver is getting
6280 initialized. Once we will move to 2.6.37 kernel, in which we have
6281 frame register ops, we will move this code as a part of that */
6282 /* GAS Initial Request */
6283
6284 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6285 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6286
6287 /* GAS Initial Response */
6288 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6289 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306290
Jeff Johnson295189b2012-06-20 16:38:30 -07006291 /* GAS Comeback Request */
6292 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6293 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6294
6295 /* GAS Comeback Response */
6296 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6297 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6298
6299 /* P2P Public Action */
6300 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306301 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006302 P2P_PUBLIC_ACTION_FRAME_SIZE );
6303
6304 /* P2P Action */
6305 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6306 (v_U8_t*)P2P_ACTION_FRAME,
6307 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006308 /* WNM-Notification */
6309 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6310 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6311 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006312}
6313
6314#ifdef FEATURE_WLAN_WAPI
6315void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05306316 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006317{
6318 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6319 tCsrRoamSetKey setKey;
6320 v_BOOL_t isConnected = TRUE;
6321 int status = 0;
6322 v_U32_t roamId= 0xFF;
6323 tANI_U8 *pKeyPtr = NULL;
6324 int n = 0;
6325
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306326 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
6327 __func__, hdd_device_modetoString(pAdapter->device_mode),
6328 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006329
Gopichand Nakkalae7480202013-02-11 15:24:22 +05306330 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006331 setKey.keyId = key_index; // Store Key ID
6332 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
6333 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
6334 setKey.paeRole = 0 ; // the PAE role
6335 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
6336 {
6337 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
6338 }
6339 else
6340 {
6341 isConnected = hdd_connIsConnected(pHddStaCtx);
6342 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
6343 }
6344 setKey.keyLength = key_Len;
6345 pKeyPtr = setKey.Key;
6346 memcpy( pKeyPtr, key, key_Len);
6347
Arif Hussain6d2a3322013-11-17 19:50:10 -08006348 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07006349 __func__, key_Len);
6350 for (n = 0 ; n < key_Len; n++)
6351 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
6352 __func__,n,setKey.Key[n]);
6353
6354 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
6355 if ( isConnected )
6356 {
6357 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
6358 pAdapter->sessionId, &setKey, &roamId );
6359 }
6360 if ( status != 0 )
6361 {
6362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6363 "[%4d] sme_RoamSetKey returned ERROR status= %d",
6364 __LINE__, status );
6365 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
6366 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05306367 /* Need to clear any trace of key value in the memory.
6368 * Thus zero out the memory even though it is local
6369 * variable.
6370 */
6371 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006372}
6373#endif /* FEATURE_WLAN_WAPI*/
6374
6375#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306376int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006377 beacon_data_t **ppBeacon,
6378 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006379#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306380int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006381 beacon_data_t **ppBeacon,
6382 struct cfg80211_beacon_data *params,
6383 int dtim_period)
6384#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306385{
Jeff Johnson295189b2012-06-20 16:38:30 -07006386 int size;
6387 beacon_data_t *beacon = NULL;
6388 beacon_data_t *old = NULL;
6389 int head_len,tail_len;
6390
Jeff Johnsone7245742012-09-05 17:12:55 -07006391 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006392 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306393 {
6394 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6395 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006396 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306397 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006398
6399 old = pAdapter->sessionCtx.ap.beacon;
6400
6401 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306402 {
6403 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6404 FL("session(%d) old and new heads points to NULL"),
6405 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006406 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306407 }
6408
6409 if (params->tail && !params->tail_len)
6410 {
6411 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6412 FL("tail_len is zero but tail is not NULL"));
6413 return -EINVAL;
6414 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006415
Jeff Johnson295189b2012-06-20 16:38:30 -07006416#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
6417 /* Kernel 3.0 is not updating dtim_period for set beacon */
6418 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306419 {
6420 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6421 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006422 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306423 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006424#endif
6425
6426 if(params->head)
6427 head_len = params->head_len;
6428 else
6429 head_len = old->head_len;
6430
6431 if(params->tail || !old)
6432 tail_len = params->tail_len;
6433 else
6434 tail_len = old->tail_len;
6435
6436 size = sizeof(beacon_data_t) + head_len + tail_len;
6437
6438 beacon = kzalloc(size, GFP_KERNEL);
6439
6440 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306441 {
6442 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6443 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006444 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306445 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006446
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006447#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006448 if(params->dtim_period || !old )
6449 beacon->dtim_period = params->dtim_period;
6450 else
6451 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006452#else
6453 if(dtim_period || !old )
6454 beacon->dtim_period = dtim_period;
6455 else
6456 beacon->dtim_period = old->dtim_period;
6457#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306458
Jeff Johnson295189b2012-06-20 16:38:30 -07006459 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6460 beacon->tail = beacon->head + head_len;
6461 beacon->head_len = head_len;
6462 beacon->tail_len = tail_len;
6463
6464 if(params->head) {
6465 memcpy (beacon->head,params->head,beacon->head_len);
6466 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306467 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07006468 if(old)
6469 memcpy (beacon->head,old->head,beacon->head_len);
6470 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306471
Jeff Johnson295189b2012-06-20 16:38:30 -07006472 if(params->tail) {
6473 memcpy (beacon->tail,params->tail,beacon->tail_len);
6474 }
6475 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306476 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07006477 memcpy (beacon->tail,old->tail,beacon->tail_len);
6478 }
6479
6480 *ppBeacon = beacon;
6481
6482 kfree(old);
6483
6484 return 0;
6485
6486}
Jeff Johnson295189b2012-06-20 16:38:30 -07006487
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05306488v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
6489#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6490 const v_U8_t *pIes,
6491#else
6492 v_U8_t *pIes,
6493#endif
6494 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006495{
6496 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05306497 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07006498 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306499
Jeff Johnson295189b2012-06-20 16:38:30 -07006500 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306501 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006502 elem_id = ptr[0];
6503 elem_len = ptr[1];
6504 left -= 2;
6505 if(elem_len > left)
6506 {
6507 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006508 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006509 eid,elem_len,left);
6510 return NULL;
6511 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306512 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006513 {
6514 return ptr;
6515 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306516
Jeff Johnson295189b2012-06-20 16:38:30 -07006517 left -= elem_len;
6518 ptr += (elem_len + 2);
6519 }
6520 return NULL;
6521}
6522
Jeff Johnson295189b2012-06-20 16:38:30 -07006523/* Check if rate is 11g rate or not */
6524static int wlan_hdd_rate_is_11g(u8 rate)
6525{
Sanjay Devnani28322e22013-06-21 16:13:40 -07006526 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006527 u8 i;
6528 for (i = 0; i < 8; i++)
6529 {
6530 if(rate == gRateArray[i])
6531 return TRUE;
6532 }
6533 return FALSE;
6534}
6535
6536/* Check for 11g rate and set proper 11g only mode */
6537static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
6538 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
6539{
6540 u8 i, num_rates = pIe[0];
6541
6542 pIe += 1;
6543 for ( i = 0; i < num_rates; i++)
6544 {
6545 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
6546 {
6547 /* If rate set have 11g rate than change the mode to 11G */
6548 *pSapHw_mode = eSAP_DOT11_MODE_11g;
6549 if (pIe[i] & BASIC_RATE_MASK)
6550 {
6551 /* If we have 11g rate as basic rate, it means mode
6552 is 11g only mode.
6553 */
6554 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
6555 *pCheckRatesfor11g = FALSE;
6556 }
6557 }
6558 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
6559 {
6560 *require_ht = TRUE;
6561 }
6562 }
6563 return;
6564}
6565
6566static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
6567{
6568 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6569 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6570 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6571 u8 checkRatesfor11g = TRUE;
6572 u8 require_ht = FALSE;
6573 u8 *pIe=NULL;
6574
6575 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
6576
6577 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
6578 pBeacon->head_len, WLAN_EID_SUPP_RATES);
6579 if (pIe != NULL)
6580 {
6581 pIe += 1;
6582 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6583 &pConfig->SapHw_mode);
6584 }
6585
6586 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6587 WLAN_EID_EXT_SUPP_RATES);
6588 if (pIe != NULL)
6589 {
6590
6591 pIe += 1;
6592 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6593 &pConfig->SapHw_mode);
6594 }
6595
6596 if( pConfig->channel > 14 )
6597 {
6598 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
6599 }
6600
6601 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6602 WLAN_EID_HT_CAPABILITY);
6603
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306604 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006605 {
6606 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
6607 if(require_ht)
6608 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
6609 }
6610}
6611
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306612static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
6613 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
6614{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006615 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306616 v_U8_t *pIe = NULL;
6617 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6618
6619 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
6620 pBeacon->tail, pBeacon->tail_len);
6621
6622 if (pIe)
6623 {
6624 ielen = pIe[1] + 2;
6625 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6626 {
6627 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
6628 }
6629 else
6630 {
6631 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
6632 return -EINVAL;
6633 }
6634 *total_ielen += ielen;
6635 }
6636 return 0;
6637}
6638
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006639static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
6640 v_U8_t *genie, v_U8_t *total_ielen)
6641{
6642 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6643 int left = pBeacon->tail_len;
6644 v_U8_t *ptr = pBeacon->tail;
6645 v_U8_t elem_id, elem_len;
6646 v_U16_t ielen = 0;
6647
6648 if ( NULL == ptr || 0 == left )
6649 return;
6650
6651 while (left >= 2)
6652 {
6653 elem_id = ptr[0];
6654 elem_len = ptr[1];
6655 left -= 2;
6656 if (elem_len > left)
6657 {
6658 hddLog( VOS_TRACE_LEVEL_ERROR,
6659 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
6660 elem_id, elem_len, left);
6661 return;
6662 }
6663 if (IE_EID_VENDOR == elem_id)
6664 {
6665 /* skipping the VSIE's which we don't want to include or
6666 * it will be included by existing code
6667 */
6668 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
6669#ifdef WLAN_FEATURE_WFD
6670 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
6671#endif
6672 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6673 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6674 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
6675 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6676 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
6677 {
6678 ielen = ptr[1] + 2;
6679 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6680 {
6681 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
6682 *total_ielen += ielen;
6683 }
6684 else
6685 {
6686 hddLog( VOS_TRACE_LEVEL_ERROR,
6687 "IE Length is too big "
6688 "IEs eid=%d elem_len=%d total_ie_lent=%d",
6689 elem_id, elem_len, *total_ielen);
6690 }
6691 }
6692 }
6693
6694 left -= elem_len;
6695 ptr += (elem_len + 2);
6696 }
6697 return;
6698}
6699
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006700#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006701static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6702 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006703#else
6704static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6705 struct cfg80211_beacon_data *params)
6706#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006707{
6708 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306709 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006710 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07006711 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006712
6713 genie = vos_mem_malloc(MAX_GENIE_LEN);
6714
6715 if(genie == NULL) {
6716
6717 return -ENOMEM;
6718 }
6719
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306720 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6721 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006722 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306723 hddLog(LOGE,
6724 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306725 ret = -EINVAL;
6726 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006727 }
6728
6729#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306730 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6731 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
6732 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306733 hddLog(LOGE,
6734 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306735 ret = -EINVAL;
6736 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006737 }
6738#endif
6739
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306740 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6741 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006742 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306743 hddLog(LOGE,
6744 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306745 ret = -EINVAL;
6746 goto done;
6747 }
6748
6749 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
6750 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006751 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07006752 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006753
6754 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6755 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
6756 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
6757 {
6758 hddLog(LOGE,
6759 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006760 ret = -EINVAL;
6761 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006762 }
6763
6764 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6765 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6766 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6767 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6768 ==eHAL_STATUS_FAILURE)
6769 {
6770 hddLog(LOGE,
6771 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006772 ret = -EINVAL;
6773 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006774 }
6775
6776 // Added for ProResp IE
6777 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
6778 {
6779 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
6780 u8 probe_rsp_ie_len[3] = {0};
6781 u8 counter = 0;
6782 /* Check Probe Resp Length if it is greater then 255 then Store
6783 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
6784 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
6785 Store More then 255 bytes into One Variable.
6786 */
6787 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6788 {
6789 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6790 {
6791 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6792 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6793 }
6794 else
6795 {
6796 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6797 rem_probe_resp_ie_len = 0;
6798 }
6799 }
6800
6801 rem_probe_resp_ie_len = 0;
6802
6803 if (probe_rsp_ie_len[0] > 0)
6804 {
6805 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6806 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6807 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6808 probe_rsp_ie_len[0], NULL,
6809 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6810 {
6811 hddLog(LOGE,
6812 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006813 ret = -EINVAL;
6814 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006815 }
6816 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6817 }
6818
6819 if (probe_rsp_ie_len[1] > 0)
6820 {
6821 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6822 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6823 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6824 probe_rsp_ie_len[1], NULL,
6825 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6826 {
6827 hddLog(LOGE,
6828 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006829 ret = -EINVAL;
6830 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006831 }
6832 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6833 }
6834
6835 if (probe_rsp_ie_len[2] > 0)
6836 {
6837 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6838 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6839 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6840 probe_rsp_ie_len[2], NULL,
6841 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6842 {
6843 hddLog(LOGE,
6844 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006845 ret = -EINVAL;
6846 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006847 }
6848 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6849 }
6850
6851 if (probe_rsp_ie_len[1] == 0 )
6852 {
6853 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6854 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6855 eANI_BOOLEAN_FALSE) )
6856 {
6857 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006858 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006859 }
6860 }
6861
6862 if (probe_rsp_ie_len[2] == 0 )
6863 {
6864 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6865 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6866 eANI_BOOLEAN_FALSE) )
6867 {
6868 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006869 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006870 }
6871 }
6872
6873 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6874 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6875 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6876 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6877 == eHAL_STATUS_FAILURE)
6878 {
6879 hddLog(LOGE,
6880 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006881 ret = -EINVAL;
6882 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006883 }
6884 }
6885 else
6886 {
6887 // Reset WNI_CFG_PROBE_RSP Flags
6888 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
6889
6890 hddLog(VOS_TRACE_LEVEL_INFO,
6891 "%s: No Probe Response IE received in set beacon",
6892 __func__);
6893 }
6894
6895 // Added for AssocResp IE
6896 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
6897 {
6898 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6899 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
6900 params->assocresp_ies_len, NULL,
6901 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6902 {
6903 hddLog(LOGE,
6904 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006905 ret = -EINVAL;
6906 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006907 }
6908
6909 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6910 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
6911 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6912 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6913 == eHAL_STATUS_FAILURE)
6914 {
6915 hddLog(LOGE,
6916 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006917 ret = -EINVAL;
6918 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006919 }
6920 }
6921 else
6922 {
6923 hddLog(VOS_TRACE_LEVEL_INFO,
6924 "%s: No Assoc Response IE received in set beacon",
6925 __func__);
6926
6927 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6928 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6929 eANI_BOOLEAN_FALSE) )
6930 {
6931 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006932 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006933 }
6934 }
6935
Jeff Johnsone7245742012-09-05 17:12:55 -07006936done:
Jeff Johnson295189b2012-06-20 16:38:30 -07006937 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306938 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006939}
Jeff Johnson295189b2012-06-20 16:38:30 -07006940
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306941/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006942 * FUNCTION: wlan_hdd_validate_operation_channel
6943 * called by wlan_hdd_cfg80211_start_bss() and
6944 * wlan_hdd_cfg80211_set_channel()
6945 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306946 * channel list.
6947 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006948VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006949{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306950
Jeff Johnson295189b2012-06-20 16:38:30 -07006951 v_U32_t num_ch = 0;
6952 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6953 u32 indx = 0;
6954 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306955 v_U8_t fValidChannel = FALSE, count = 0;
6956 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306957
Jeff Johnson295189b2012-06-20 16:38:30 -07006958 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6959
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306960 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006961 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306962 /* Validate the channel */
6963 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006964 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306965 if ( channel == rfChannels[count].channelNum )
6966 {
6967 fValidChannel = TRUE;
6968 break;
6969 }
6970 }
6971 if (fValidChannel != TRUE)
6972 {
6973 hddLog(VOS_TRACE_LEVEL_ERROR,
6974 "%s: Invalid Channel [%d]", __func__, channel);
6975 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006976 }
6977 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306978 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006979 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306980 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6981 valid_ch, &num_ch))
6982 {
6983 hddLog(VOS_TRACE_LEVEL_ERROR,
6984 "%s: failed to get valid channel list", __func__);
6985 return VOS_STATUS_E_FAILURE;
6986 }
6987 for (indx = 0; indx < num_ch; indx++)
6988 {
6989 if (channel == valid_ch[indx])
6990 {
6991 break;
6992 }
6993 }
6994
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306995 if (indx >= num_ch)
6996 {
6997 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6998 {
6999 eCsrBand band;
7000 unsigned int freq;
7001
7002 sme_GetFreqBand(hHal, &band);
7003
7004 if (eCSR_BAND_5G == band)
7005 {
7006#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
7007 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
7008 {
7009 freq = ieee80211_channel_to_frequency(channel,
7010 IEEE80211_BAND_2GHZ);
7011 }
7012 else
7013 {
7014 freq = ieee80211_channel_to_frequency(channel,
7015 IEEE80211_BAND_5GHZ);
7016 }
7017#else
7018 freq = ieee80211_channel_to_frequency(channel);
7019#endif
7020 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
7021 return VOS_STATUS_SUCCESS;
7022 }
7023 }
7024
7025 hddLog(VOS_TRACE_LEVEL_ERROR,
7026 "%s: Invalid Channel [%d]", __func__, channel);
7027 return VOS_STATUS_E_FAILURE;
7028 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007029 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05307030
Jeff Johnson295189b2012-06-20 16:38:30 -07007031 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307032
Jeff Johnson295189b2012-06-20 16:38:30 -07007033}
7034
Viral Modi3a32cc52013-02-08 11:14:52 -08007035/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307036 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08007037 * This function is used to set the channel number
7038 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307039static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08007040 struct ieee80211_channel *chan,
7041 enum nl80211_channel_type channel_type
7042 )
7043{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307044 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08007045 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07007046 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08007047 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307048 hdd_context_t *pHddCtx;
7049 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007050
7051 ENTER();
7052
7053 if( NULL == dev )
7054 {
7055 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007056 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08007057 return -ENODEV;
7058 }
7059 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307060
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307061 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7062 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
7063 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08007064 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307065 "%s: device_mode = %s (%d) freq = %d", __func__,
7066 hdd_device_modetoString(pAdapter->device_mode),
7067 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307068
7069 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7070 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307071 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08007072 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307073 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007074 }
7075
7076 /*
7077 * Do freq to chan conversion
7078 * TODO: for 11a
7079 */
7080
7081 channel = ieee80211_frequency_to_channel(freq);
7082
7083 /* Check freq range */
7084 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
7085 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
7086 {
7087 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007088 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08007089 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
7090 WNI_CFG_CURRENT_CHANNEL_STAMAX);
7091 return -EINVAL;
7092 }
7093
7094 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
7095
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05307096 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
7097 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08007098 {
7099 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
7100 {
7101 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007102 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08007103 return -EINVAL;
7104 }
7105 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
7106 "%s: set channel to [%d] for device mode =%d",
7107 __func__, channel,pAdapter->device_mode);
7108 }
7109 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08007110 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08007111 )
7112 {
7113 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
7114 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
7115 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7116
7117 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
7118 {
7119 /* Link is up then return cant set channel*/
7120 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007121 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08007122 return -EINVAL;
7123 }
7124
7125 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
7126 pHddStaCtx->conn_info.operationChannel = channel;
7127 pRoamProfile->ChannelInfo.ChannelList =
7128 &pHddStaCtx->conn_info.operationChannel;
7129 }
7130 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08007131 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08007132 )
7133 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307134 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
7135 {
7136 if(VOS_STATUS_SUCCESS !=
7137 wlan_hdd_validate_operation_channel(pAdapter,channel))
7138 {
7139 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007140 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307141 return -EINVAL;
7142 }
7143 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7144 }
7145 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08007146 {
7147 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
7148
7149 /* If auto channel selection is configured as enable/ 1 then ignore
7150 channel set by supplicant
7151 */
7152 if ( cfg_param->apAutoChannelSelection )
7153 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307154 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
7155 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08007156 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307157 "%s: set channel to auto channel (0) for device mode =%s (%d)",
7158 __func__, hdd_device_modetoString(pAdapter->device_mode),
7159 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08007160 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307161 else
7162 {
7163 if(VOS_STATUS_SUCCESS !=
7164 wlan_hdd_validate_operation_channel(pAdapter,channel))
7165 {
7166 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007167 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307168 return -EINVAL;
7169 }
7170 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7171 }
Viral Modi3a32cc52013-02-08 11:14:52 -08007172 }
7173 }
7174 else
7175 {
7176 hddLog(VOS_TRACE_LEVEL_FATAL,
7177 "%s: Invalid device mode failed to set valid channel", __func__);
7178 return -EINVAL;
7179 }
7180 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307181 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007182}
7183
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307184static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
7185 struct net_device *dev,
7186 struct ieee80211_channel *chan,
7187 enum nl80211_channel_type channel_type
7188 )
7189{
7190 int ret;
7191
7192 vos_ssr_protect(__func__);
7193 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
7194 vos_ssr_unprotect(__func__);
7195
7196 return ret;
7197}
7198
Jeff Johnson295189b2012-06-20 16:38:30 -07007199#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7200static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7201 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007202#else
7203static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7204 struct cfg80211_beacon_data *params,
7205 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307206 enum nl80211_hidden_ssid hidden_ssid,
7207 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007208#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007209{
7210 tsap_Config_t *pConfig;
7211 beacon_data_t *pBeacon = NULL;
7212 struct ieee80211_mgmt *pMgmt_frame;
7213 v_U8_t *pIe=NULL;
7214 v_U16_t capab_info;
7215 eCsrAuthType RSNAuthType;
7216 eCsrEncryptionType RSNEncryptType;
7217 eCsrEncryptionType mcRSNEncryptType;
7218 int status = VOS_STATUS_SUCCESS;
7219 tpWLAN_SAPEventCB pSapEventCallback;
7220 hdd_hostapd_state_t *pHostapdState;
7221 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
7222 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307223 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007224 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307225 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07007226 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08007227 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05307228 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07007229 v_BOOL_t MFPCapable = VOS_FALSE;
7230 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307231 v_BOOL_t sapEnable11AC =
7232 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07007233 ENTER();
7234
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307235 iniConfig = pHddCtx->cfg_ini;
7236
Jeff Johnson295189b2012-06-20 16:38:30 -07007237 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
7238
7239 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7240
7241 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7242
7243 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
7244
7245 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
7246
7247 //channel is already set in the set_channel Call back
7248 //pConfig->channel = pCommitConfig->channel;
7249
7250 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307251 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07007252 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
7253
7254 pConfig->dtim_period = pBeacon->dtim_period;
7255
Arif Hussain6d2a3322013-11-17 19:50:10 -08007256 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07007257 pConfig->dtim_period);
7258
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08007259 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07007260 {
7261 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007262 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05307263 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
7264 {
7265 tANI_BOOLEAN restartNeeded;
7266 pConfig->ieee80211d = 1;
7267 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
7268 sme_setRegInfo(hHal, pConfig->countryCode);
7269 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
7270 }
7271 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07007272 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07007273 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07007274 pConfig->ieee80211d = 1;
7275 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
7276 sme_setRegInfo(hHal, pConfig->countryCode);
7277 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07007278 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007279 else
7280 {
7281 pConfig->ieee80211d = 0;
7282 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307283 /*
7284 * If auto channel is configured i.e. channel is 0,
7285 * so skip channel validation.
7286 */
7287 if( AUTO_CHANNEL_SELECT != pConfig->channel )
7288 {
7289 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
7290 {
7291 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007292 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307293 return -EINVAL;
7294 }
7295 }
7296 else
7297 {
7298 if(1 != pHddCtx->is_dynamic_channel_range_set)
7299 {
7300 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
7301 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
7302 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
7303 }
7304 pHddCtx->is_dynamic_channel_range_set = 0;
7305 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007306 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007307 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007308 {
7309 pConfig->ieee80211d = 0;
7310 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307311
7312#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7313 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7314 pConfig->authType = eSAP_OPEN_SYSTEM;
7315 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7316 pConfig->authType = eSAP_SHARED_KEY;
7317 else
7318 pConfig->authType = eSAP_AUTO_SWITCH;
7319#else
7320 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7321 pConfig->authType = eSAP_OPEN_SYSTEM;
7322 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7323 pConfig->authType = eSAP_SHARED_KEY;
7324 else
7325 pConfig->authType = eSAP_AUTO_SWITCH;
7326#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007327
7328 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307329
7330 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07007331 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
7332
7333 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
7334
7335 /*Set wps station to configured*/
7336 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
7337
7338 if(pIe)
7339 {
7340 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
7341 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007342 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07007343 return -EINVAL;
7344 }
7345 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
7346 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007347 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07007348 /* Check 15 bit of WPS IE as it contain information for wps state
7349 * WPS state
7350 */
7351 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
7352 {
7353 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
7354 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
7355 {
7356 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
7357 }
7358 }
7359 }
7360 else
7361 {
7362 pConfig->wps_state = SAP_WPS_DISABLED;
7363 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307364 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07007365
c_hpothufe599e92014-06-16 11:38:55 +05307366 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7367 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7368 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
7369 eCSR_ENCRYPT_TYPE_NONE;
7370
Jeff Johnson295189b2012-06-20 16:38:30 -07007371 pConfig->RSNWPAReqIELength = 0;
7372 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307373 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007374 WLAN_EID_RSN);
7375 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307376 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007377 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7378 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7379 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307380 /* The actual processing may eventually be more extensive than
7381 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07007382 * by the app.
7383 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307384 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007385 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7386 &RSNEncryptType,
7387 &mcRSNEncryptType,
7388 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007389 &MFPCapable,
7390 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007391 pConfig->pRSNWPAReqIE[1]+2,
7392 pConfig->pRSNWPAReqIE );
7393
7394 if( VOS_STATUS_SUCCESS == status )
7395 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307396 /* Now copy over all the security attributes you have
7397 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007398 * */
7399 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7400 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7401 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7402 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307403 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007404 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007405 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7406 }
7407 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307408
Jeff Johnson295189b2012-06-20 16:38:30 -07007409 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7410 pBeacon->tail, pBeacon->tail_len);
7411
7412 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
7413 {
7414 if (pConfig->pRSNWPAReqIE)
7415 {
7416 /*Mixed mode WPA/WPA2*/
7417 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
7418 pConfig->RSNWPAReqIELength += pIe[1] + 2;
7419 }
7420 else
7421 {
7422 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7423 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7424 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307425 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007426 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7427 &RSNEncryptType,
7428 &mcRSNEncryptType,
7429 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007430 &MFPCapable,
7431 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007432 pConfig->pRSNWPAReqIE[1]+2,
7433 pConfig->pRSNWPAReqIE );
7434
7435 if( VOS_STATUS_SUCCESS == status )
7436 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307437 /* Now copy over all the security attributes you have
7438 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007439 * */
7440 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7441 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7442 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7443 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307444 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007445 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007446 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7447 }
7448 }
7449 }
7450
Jeff Johnson4416a782013-03-25 14:17:50 -07007451 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
7452 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
7453 return -EINVAL;
7454 }
7455
Jeff Johnson295189b2012-06-20 16:38:30 -07007456 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
7457
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007458#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007459 if (params->ssid != NULL)
7460 {
7461 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
7462 pConfig->SSIDinfo.ssid.length = params->ssid_len;
7463 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7464 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7465 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007466#else
7467 if (ssid != NULL)
7468 {
7469 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
7470 pConfig->SSIDinfo.ssid.length = ssid_len;
7471 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7472 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7473 }
7474#endif
7475
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307476 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07007477 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307478
Jeff Johnson295189b2012-06-20 16:38:30 -07007479 /* default value */
7480 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7481 pConfig->num_accept_mac = 0;
7482 pConfig->num_deny_mac = 0;
7483
7484 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7485 pBeacon->tail, pBeacon->tail_len);
7486
7487 /* pIe for black list is following form:
7488 type : 1 byte
7489 length : 1 byte
7490 OUI : 4 bytes
7491 acl type : 1 byte
7492 no of mac addr in black list: 1 byte
7493 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307494 */
7495 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007496 {
7497 pConfig->SapMacaddr_acl = pIe[6];
7498 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007499 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007500 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307501 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
7502 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007503 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7504 for (i = 0; i < pConfig->num_deny_mac; i++)
7505 {
7506 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7507 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307508 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007509 }
7510 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7511 pBeacon->tail, pBeacon->tail_len);
7512
7513 /* pIe for white list is following form:
7514 type : 1 byte
7515 length : 1 byte
7516 OUI : 4 bytes
7517 acl type : 1 byte
7518 no of mac addr in white list: 1 byte
7519 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307520 */
7521 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007522 {
7523 pConfig->SapMacaddr_acl = pIe[6];
7524 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007525 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007526 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307527 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
7528 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007529 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7530 for (i = 0; i < pConfig->num_accept_mac; i++)
7531 {
7532 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7533 acl_entry++;
7534 }
7535 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307536
Jeff Johnson295189b2012-06-20 16:38:30 -07007537 wlan_hdd_set_sapHwmode(pHostapdAdapter);
7538
Jeff Johnsone7245742012-09-05 17:12:55 -07007539#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007540 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307541 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
7542 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05307543 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
7544 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007545 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
7546 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307547 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
7548 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07007549 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307550 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07007551 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307552 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007553
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307554 /* If ACS disable and selected channel <= 14
7555 * OR
7556 * ACS enabled and ACS operating band is choosen as 2.4
7557 * AND
7558 * VHT in 2.4G Disabled
7559 * THEN
7560 * Fallback to 11N mode
7561 */
7562 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
7563 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05307564 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307565 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007566 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307567 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
7568 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007569 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
7570 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007571 }
7572#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307573
Jeff Johnson295189b2012-06-20 16:38:30 -07007574 // ht_capab is not what the name conveys,this is used for protection bitmap
7575 pConfig->ht_capab =
7576 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
7577
7578 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
7579 {
7580 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
7581 return -EINVAL;
7582 }
7583
7584 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307585 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07007586 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
7587 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307588 pConfig->obssProtEnabled =
7589 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07007590
Chet Lanctot8cecea22014-02-11 19:09:36 -08007591#ifdef WLAN_FEATURE_11W
7592 pConfig->mfpCapable = MFPCapable;
7593 pConfig->mfpRequired = MFPRequired;
7594 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
7595 pConfig->mfpCapable, pConfig->mfpRequired);
7596#endif
7597
Arif Hussain6d2a3322013-11-17 19:50:10 -08007598 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07007599 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007600 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
7601 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
7602 (int)pConfig->channel);
7603 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
7604 pConfig->SapHw_mode, pConfig->privacy,
7605 pConfig->authType);
7606 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
7607 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
7608 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
7609 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07007610
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307611 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007612 {
7613 //Bss already started. just return.
7614 //TODO Probably it should update some beacon params.
7615 hddLog( LOGE, "Bss Already started...Ignore the request");
7616 EXIT();
7617 return 0;
7618 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307619
Agarwal Ashish51325b52014-06-16 16:50:49 +05307620 if (vos_max_concurrent_connections_reached()) {
7621 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7622 return -EINVAL;
7623 }
7624
Jeff Johnson295189b2012-06-20 16:38:30 -07007625 pConfig->persona = pHostapdAdapter->device_mode;
7626
Peng Xu2446a892014-09-05 17:21:18 +05307627 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
7628 if ( NULL != psmeConfig)
7629 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307630 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05307631 sme_GetConfigParam(hHal, psmeConfig);
7632 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307633#ifdef WLAN_FEATURE_AP_HT40_24G
7634 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
7635 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
7636 && pHddCtx->cfg_ini->apHT40_24GEnabled)
7637 {
7638 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
7639 sme_UpdateConfig (hHal, psmeConfig);
7640 }
7641#endif
Peng Xu2446a892014-09-05 17:21:18 +05307642 vos_mem_free(psmeConfig);
7643 }
Peng Xuafc34e32014-09-25 13:23:55 +05307644 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05307645
Jeff Johnson295189b2012-06-20 16:38:30 -07007646 pSapEventCallback = hdd_hostapd_SAPEventCB;
7647 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
7648 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
7649 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007650 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007651 return -EINVAL;
7652 }
7653
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307654 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07007655 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
7656
7657 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307658
Jeff Johnson295189b2012-06-20 16:38:30 -07007659 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307660 {
7661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007662 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07007663 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07007664 VOS_ASSERT(0);
7665 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307666
Jeff Johnson295189b2012-06-20 16:38:30 -07007667 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05307668 /* Initialize WMM configuation */
7669 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307670 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007671
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007672#ifdef WLAN_FEATURE_P2P_DEBUG
7673 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
7674 {
7675 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
7676 {
7677 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7678 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007679 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007680 }
7681 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
7682 {
7683 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7684 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007685 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007686 }
7687 }
7688#endif
7689
Jeff Johnson295189b2012-06-20 16:38:30 -07007690 pHostapdState->bCommit = TRUE;
7691 EXIT();
7692
7693 return 0;
7694}
7695
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007696#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307697static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307698 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007699 struct beacon_parameters *params)
7700{
7701 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307702 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307703 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007704
7705 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307706
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307707 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7708 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
7709 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307710 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
7711 hdd_device_modetoString(pAdapter->device_mode),
7712 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007713
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307714 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7715 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307716 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007717 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307718 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007719 }
7720
Agarwal Ashish51325b52014-06-16 16:50:49 +05307721 if (vos_max_concurrent_connections_reached()) {
7722 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7723 return -EINVAL;
7724 }
7725
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307726 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007727 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007728 )
7729 {
7730 beacon_data_t *old,*new;
7731
7732 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307733
Jeff Johnson295189b2012-06-20 16:38:30 -07007734 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307735 {
7736 hddLog(VOS_TRACE_LEVEL_WARN,
7737 FL("already beacon info added to session(%d)"),
7738 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007739 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307740 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007741
7742 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7743
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307744 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07007745 {
7746 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007747 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007748 return -EINVAL;
7749 }
7750
7751 pAdapter->sessionCtx.ap.beacon = new;
7752
7753 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7754 }
7755
7756 EXIT();
7757 return status;
7758}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307759
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307760static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
7761 struct net_device *dev,
7762 struct beacon_parameters *params)
7763{
7764 int ret;
7765
7766 vos_ssr_protect(__func__);
7767 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
7768 vos_ssr_unprotect(__func__);
7769
7770 return ret;
7771}
7772
7773static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007774 struct net_device *dev,
7775 struct beacon_parameters *params)
7776{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307777 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307778 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7779 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307780 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007781
7782 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307783
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307784 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7785 TRACE_CODE_HDD_CFG80211_SET_BEACON,
7786 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
7787 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7788 __func__, hdd_device_modetoString(pAdapter->device_mode),
7789 pAdapter->device_mode);
7790
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307791 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7792 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307793 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007794 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307795 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007796 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307797
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307798 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007799 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307800 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007801 {
7802 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307803
Jeff Johnson295189b2012-06-20 16:38:30 -07007804 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307805
Jeff Johnson295189b2012-06-20 16:38:30 -07007806 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307807 {
7808 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7809 FL("session(%d) old and new heads points to NULL"),
7810 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007811 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307812 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007813
7814 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7815
7816 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307817 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007818 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007819 return -EINVAL;
7820 }
7821
7822 pAdapter->sessionCtx.ap.beacon = new;
7823
7824 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7825 }
7826
7827 EXIT();
7828 return status;
7829}
7830
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307831static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
7832 struct net_device *dev,
7833 struct beacon_parameters *params)
7834{
7835 int ret;
7836
7837 vos_ssr_protect(__func__);
7838 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
7839 vos_ssr_unprotect(__func__);
7840
7841 return ret;
7842}
7843
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007844#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7845
7846#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307847static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007848 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007849#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307850static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007851 struct net_device *dev)
7852#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007853{
7854 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07007855 hdd_context_t *pHddCtx = NULL;
7856 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307857 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307858 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007859
7860 ENTER();
7861
7862 if (NULL == pAdapter)
7863 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307864 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007865 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007866 return -ENODEV;
7867 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007868
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307869 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7870 TRACE_CODE_HDD_CFG80211_STOP_AP,
7871 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307872 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7873 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307874 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007875 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307876 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07007877 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007878
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007879 pScanInfo = &pHddCtx->scan_info;
7880
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307881 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7882 __func__, hdd_device_modetoString(pAdapter->device_mode),
7883 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007884
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307885 ret = wlan_hdd_scan_abort(pAdapter);
7886
Girish Gowli4bf7a632014-06-12 13:42:11 +05307887 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07007888 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307889 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7890 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307891
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307892 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07007893 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307894 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7895 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08007896
Jeff Johnsone7245742012-09-05 17:12:55 -07007897 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307898 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07007899 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307900 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07007901 }
7902
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05307903 /* Delete all associated STAs before stopping AP/P2P GO */
7904 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05307905 hdd_hostapd_stop(dev);
7906
Jeff Johnson295189b2012-06-20 16:38:30 -07007907 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007908 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007909 )
7910 {
7911 beacon_data_t *old;
7912
7913 old = pAdapter->sessionCtx.ap.beacon;
7914
7915 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307916 {
7917 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7918 FL("session(%d) beacon data points to NULL"),
7919 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007920 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307921 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007922
Jeff Johnson295189b2012-06-20 16:38:30 -07007923 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007924
7925 mutex_lock(&pHddCtx->sap_lock);
7926 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7927 {
Jeff Johnson4416a782013-03-25 14:17:50 -07007928 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007929 {
7930 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7931
7932 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7933
7934 if (!VOS_IS_STATUS_SUCCESS(status))
7935 {
7936 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007937 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007938 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307939 }
7940 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007941 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307942 /* BSS stopped, clear the active sessions for this device mode */
7943 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007944 }
7945 mutex_unlock(&pHddCtx->sap_lock);
7946
7947 if(status != VOS_STATUS_SUCCESS)
7948 {
7949 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007950 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007951 return -EINVAL;
7952 }
7953
Jeff Johnson4416a782013-03-25 14:17:50 -07007954 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007955 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
7956 ==eHAL_STATUS_FAILURE)
7957 {
7958 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007959 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007960 }
7961
Jeff Johnson4416a782013-03-25 14:17:50 -07007962 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007963 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7964 eANI_BOOLEAN_FALSE) )
7965 {
7966 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007967 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007968 }
7969
7970 // Reset WNI_CFG_PROBE_RSP Flags
7971 wlan_hdd_reset_prob_rspies(pAdapter);
7972
7973 pAdapter->sessionCtx.ap.beacon = NULL;
7974 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007975#ifdef WLAN_FEATURE_P2P_DEBUG
7976 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
7977 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
7978 {
7979 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
7980 "GO got removed");
7981 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
7982 }
7983#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007984 }
7985 EXIT();
7986 return status;
7987}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007988
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307989#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7990static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
7991 struct net_device *dev)
7992{
7993 int ret;
7994
7995 vos_ssr_protect(__func__);
7996 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
7997 vos_ssr_unprotect(__func__);
7998
7999 return ret;
8000}
8001#else
8002static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
8003 struct net_device *dev)
8004{
8005 int ret;
8006
8007 vos_ssr_protect(__func__);
8008 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
8009 vos_ssr_unprotect(__func__);
8010
8011 return ret;
8012}
8013#endif
8014
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008015#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
8016
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308017static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308018 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008019 struct cfg80211_ap_settings *params)
8020{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308021 hdd_adapter_t *pAdapter;
8022 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308023 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008024
8025 ENTER();
8026
Girish Gowlib143d7a2015-02-18 19:39:55 +05308027 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008028 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308029 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05308030 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308031 return -ENODEV;
8032 }
8033
8034 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8035 if (NULL == pAdapter)
8036 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308037 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308038 "%s: HDD adapter is Null", __func__);
8039 return -ENODEV;
8040 }
8041
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308042 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8043 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
8044 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308045 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
8046 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308047 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308048 "%s: HDD adapter magic is invalid", __func__);
8049 return -ENODEV;
8050 }
8051
8052 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308053 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308054 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308055 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308056 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308057 }
8058
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308059 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
8060 __func__, hdd_device_modetoString(pAdapter->device_mode),
8061 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308062
8063 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008064 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008065 )
8066 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308067 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008068
8069 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308070
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008071 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308072 {
8073 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
8074 FL("already beacon info added to session(%d)"),
8075 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008076 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308077 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008078
Girish Gowlib143d7a2015-02-18 19:39:55 +05308079#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
8080 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
8081 &new,
8082 &params->beacon);
8083#else
8084 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
8085 &new,
8086 &params->beacon,
8087 params->dtim_period);
8088#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008089
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308090 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008091 {
8092 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05308093 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008094 return -EINVAL;
8095 }
8096 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08008097#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07008098 wlan_hdd_cfg80211_set_channel(wiphy, dev,
8099#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
8100 params->channel, params->channel_type);
8101#else
8102 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
8103#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08008104#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008105 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308106 params->ssid_len, params->hidden_ssid,
8107 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008108 }
8109
8110 EXIT();
8111 return status;
8112}
8113
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308114static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
8115 struct net_device *dev,
8116 struct cfg80211_ap_settings *params)
8117{
8118 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008119
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308120 vos_ssr_protect(__func__);
8121 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
8122 vos_ssr_unprotect(__func__);
8123
8124 return ret;
8125}
8126
8127static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008128 struct net_device *dev,
8129 struct cfg80211_beacon_data *params)
8130{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308131 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308132 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308133 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008134
8135 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308136
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308137 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8138 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
8139 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08008140 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008141 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308142
8143 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8144 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308145 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008146 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308147 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008148 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008149
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308150 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008151 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308152 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008153 {
8154 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308155
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008156 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308157
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008158 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308159 {
8160 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8161 FL("session(%d) beacon data points to NULL"),
8162 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008163 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308164 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008165
8166 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
8167
8168 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308169 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008170 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008171 return -EINVAL;
8172 }
8173
8174 pAdapter->sessionCtx.ap.beacon = new;
8175
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308176 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
8177 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008178 }
8179
8180 EXIT();
8181 return status;
8182}
8183
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308184static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8185 struct net_device *dev,
8186 struct cfg80211_beacon_data *params)
8187{
8188 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008189
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308190 vos_ssr_protect(__func__);
8191 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
8192 vos_ssr_unprotect(__func__);
8193
8194 return ret;
8195}
8196
8197#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008198
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308199static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008200 struct net_device *dev,
8201 struct bss_parameters *params)
8202{
8203 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308204 hdd_context_t *pHddCtx;
8205 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008206
8207 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308208
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308209 if (NULL == pAdapter)
8210 {
8211 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8212 "%s: HDD adapter is Null", __func__);
8213 return -ENODEV;
8214 }
8215 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308216 ret = wlan_hdd_validate_context(pHddCtx);
8217 if (0 != ret)
8218 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308219 return ret;
8220 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308221 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8222 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
8223 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308224 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8225 __func__, hdd_device_modetoString(pAdapter->device_mode),
8226 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008227
8228 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008229 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308230 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008231 {
8232 /* ap_isolate == -1 means that in change bss, upper layer doesn't
8233 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308234 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07008235 {
8236 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308237 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008238 }
8239
8240 EXIT();
8241 return 0;
8242}
8243
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308244static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
8245 struct net_device *dev,
8246 struct bss_parameters *params)
8247{
8248 int ret;
8249
8250 vos_ssr_protect(__func__);
8251 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
8252 vos_ssr_unprotect(__func__);
8253
8254 return ret;
8255}
Kiet Lam10841362013-11-01 11:36:50 +05308256/* FUNCTION: wlan_hdd_change_country_code_cd
8257* to wait for contry code completion
8258*/
8259void* wlan_hdd_change_country_code_cb(void *pAdapter)
8260{
8261 hdd_adapter_t *call_back_pAdapter = pAdapter;
8262 complete(&call_back_pAdapter->change_country_code);
8263 return NULL;
8264}
8265
Jeff Johnson295189b2012-06-20 16:38:30 -07008266/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308267 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07008268 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
8269 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308270int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008271 struct net_device *ndev,
8272 enum nl80211_iftype type,
8273 u32 *flags,
8274 struct vif_params *params
8275 )
8276{
8277 struct wireless_dev *wdev;
8278 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008279 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07008280 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008281 tCsrRoamProfile *pRoamProfile = NULL;
8282 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308283 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008284 eMib_dot11DesiredBssType connectedBssType;
8285 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308286 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008287
8288 ENTER();
8289
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308290 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008291 {
8292 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8293 "%s: Adapter context is null", __func__);
8294 return VOS_STATUS_E_FAILURE;
8295 }
8296
8297 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8298 if (!pHddCtx)
8299 {
8300 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8301 "%s: HDD context is null", __func__);
8302 return VOS_STATUS_E_FAILURE;
8303 }
8304
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308305 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8306 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
8307 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308308 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308309 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07008310 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308311 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008312 }
8313
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308314 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8315 __func__, hdd_device_modetoString(pAdapter->device_mode),
8316 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008317
Agarwal Ashish51325b52014-06-16 16:50:49 +05308318 if (vos_max_concurrent_connections_reached()) {
8319 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8320 return -EINVAL;
8321 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308322 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07008323 wdev = ndev->ieee80211_ptr;
8324
8325#ifdef WLAN_BTAMP_FEATURE
8326 if((NL80211_IFTYPE_P2P_CLIENT == type)||
8327 (NL80211_IFTYPE_ADHOC == type)||
8328 (NL80211_IFTYPE_AP == type)||
8329 (NL80211_IFTYPE_P2P_GO == type))
8330 {
8331 pHddCtx->isAmpAllowed = VOS_FALSE;
8332 // stop AMP traffic
8333 status = WLANBAP_StopAmp();
8334 if(VOS_STATUS_SUCCESS != status )
8335 {
8336 pHddCtx->isAmpAllowed = VOS_TRUE;
8337 hddLog(VOS_TRACE_LEVEL_FATAL,
8338 "%s: Failed to stop AMP", __func__);
8339 return -EINVAL;
8340 }
8341 }
8342#endif //WLAN_BTAMP_FEATURE
8343 /* Reset the current device mode bit mask*/
8344 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8345
Masti, Narayanraddi575ccc72015-08-17 18:04:57 +05308346 if ((pAdapter->device_mode == WLAN_HDD_P2P_DEVICE) &&
8347 ((type == NL80211_IFTYPE_P2P_CLIENT) ||
8348 (type == NL80211_IFTYPE_P2P_GO)))
8349 {
8350 /* Notify Mode change in case of concurrency.
8351 * Below function invokes TDLS teardown Functionality Since TDLS is
8352 * not Supported in case of concurrency i.e Once P2P session
8353 * is detected disable offchannel and teardown TDLS links
8354 */
8355 hddLog(LOG1,
8356 FL("Device mode = %d Interface type = %d"),
8357 pAdapter->device_mode, type);
8358 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
8359 }
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +05308360
Jeff Johnson295189b2012-06-20 16:38:30 -07008361 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008362 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07008363 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008364 )
8365 {
8366 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008367 if (!pWextState)
8368 {
8369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8370 "%s: pWextState is null", __func__);
8371 return VOS_STATUS_E_FAILURE;
8372 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008373 pRoamProfile = &pWextState->roamProfile;
8374 LastBSSType = pRoamProfile->BSSType;
8375
8376 switch (type)
8377 {
8378 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008379 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008380 hddLog(VOS_TRACE_LEVEL_INFO,
8381 "%s: setting interface Type to INFRASTRUCTURE", __func__);
8382 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008383#ifdef WLAN_FEATURE_11AC
8384 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
8385 {
8386 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
8387 }
8388#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308389 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07008390 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008391 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008392 //Check for sub-string p2p to confirm its a p2p interface
8393 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308394 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +05308395#ifdef FEATURE_WLAN_TDLS
8396 mutex_lock(&pHddCtx->tdls_lock);
8397 wlan_hdd_tdls_exit(pAdapter, TRUE);
8398 mutex_unlock(&pHddCtx->tdls_lock);
8399#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008400 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8401 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8402 }
8403 else
8404 {
8405 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008406 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008407 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008408 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05308409
Jeff Johnson295189b2012-06-20 16:38:30 -07008410 case NL80211_IFTYPE_ADHOC:
8411 hddLog(VOS_TRACE_LEVEL_INFO,
8412 "%s: setting interface Type to ADHOC", __func__);
8413 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
8414 pRoamProfile->phyMode =
8415 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07008416 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008417 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +05308418 hdd_set_ibss_ops( pAdapter );
8419 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +05308420
8421 status = hdd_sta_id_hash_attach(pAdapter);
8422 if (VOS_STATUS_SUCCESS != status) {
8423 hddLog(VOS_TRACE_LEVEL_ERROR,
8424 FL("Failed to initialize hash for IBSS"));
8425 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008426 break;
8427
8428 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008429 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008430 {
8431 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8432 "%s: setting interface Type to %s", __func__,
8433 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
8434
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008435 //Cancel any remain on channel for GO mode
8436 if (NL80211_IFTYPE_P2P_GO == type)
8437 {
8438 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
8439 }
Mohit Khanna0f232092012-09-11 14:46:08 -07008440 if (NL80211_IFTYPE_AP == type)
8441 {
8442 /* As Loading WLAN Driver one interface being created for p2p device
8443 * address. This will take one HW STA and the max number of clients
8444 * that can connect to softAP will be reduced by one. so while changing
8445 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
8446 * interface as it is not required in SoftAP mode.
8447 */
8448
8449 // Get P2P Adapter
8450 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
8451
8452 if (pP2pAdapter)
8453 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308454 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05308455 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07008456 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
8457 }
8458 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05308459 //Disable IMPS & BMPS for SAP/GO
8460 if(VOS_STATUS_E_FAILURE ==
8461 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
8462 {
8463 //Fail to Exit BMPS
8464 VOS_ASSERT(0);
8465 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05308466
8467 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
8468
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308469#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07008470
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308471 /* A Mutex Lock is introduced while changing the mode to
8472 * protect the concurrent access for the Adapters by TDLS
8473 * module.
8474 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308475 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308476#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008477 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05308478 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008479 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07008480 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8481 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308482#ifdef FEATURE_WLAN_TDLS
8483 mutex_unlock(&pHddCtx->tdls_lock);
8484#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008485 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
8486 (pConfig->apRandomBssidEnabled))
8487 {
8488 /* To meet Android requirements create a randomized
8489 MAC address of the form 02:1A:11:Fx:xx:xx */
8490 get_random_bytes(&ndev->dev_addr[3], 3);
8491 ndev->dev_addr[0] = 0x02;
8492 ndev->dev_addr[1] = 0x1A;
8493 ndev->dev_addr[2] = 0x11;
8494 ndev->dev_addr[3] |= 0xF0;
8495 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
8496 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08008497 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
8498 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008499 }
8500
Jeff Johnson295189b2012-06-20 16:38:30 -07008501 hdd_set_ap_ops( pAdapter->dev );
8502
Kiet Lam10841362013-11-01 11:36:50 +05308503 /* This is for only SAP mode where users can
8504 * control country through ini.
8505 * P2P GO follows station country code
8506 * acquired during the STA scanning. */
8507 if((NL80211_IFTYPE_AP == type) &&
8508 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
8509 {
8510 int status = 0;
8511 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
8512 "%s: setting country code from INI ", __func__);
8513 init_completion(&pAdapter->change_country_code);
8514 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
8515 (void *)(tSmeChangeCountryCallback)
8516 wlan_hdd_change_country_code_cb,
8517 pConfig->apCntryCode, pAdapter,
8518 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308519 eSIR_FALSE,
8520 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05308521 if (eHAL_STATUS_SUCCESS == status)
8522 {
8523 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308524 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05308525 &pAdapter->change_country_code,
8526 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308527 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05308528 {
8529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308530 FL("SME Timed out while setting country code %ld"),
8531 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08008532
8533 if (pHddCtx->isLogpInProgress)
8534 {
8535 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8536 "%s: LOGP in Progress. Ignore!!!", __func__);
8537 return -EAGAIN;
8538 }
Kiet Lam10841362013-11-01 11:36:50 +05308539 }
8540 }
8541 else
8542 {
8543 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008544 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05308545 return -EINVAL;
8546 }
8547 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008548 status = hdd_init_ap_mode(pAdapter);
8549 if(status != VOS_STATUS_SUCCESS)
8550 {
8551 hddLog(VOS_TRACE_LEVEL_FATAL,
8552 "%s: Error initializing the ap mode", __func__);
8553 return -EINVAL;
8554 }
8555 hdd_set_conparam(1);
8556
Nirav Shah7e3c8132015-06-22 23:51:42 +05308557 status = hdd_sta_id_hash_attach(pAdapter);
8558 if (VOS_STATUS_SUCCESS != status)
8559 {
8560 hddLog(VOS_TRACE_LEVEL_ERROR,
8561 FL("Failed to initialize hash for AP"));
8562 return -EINVAL;
8563 }
8564
Jeff Johnson295189b2012-06-20 16:38:30 -07008565 /*interface type changed update in wiphy structure*/
8566 if(wdev)
8567 {
8568 wdev->iftype = type;
8569 pHddCtx->change_iface = type;
8570 }
8571 else
8572 {
8573 hddLog(VOS_TRACE_LEVEL_ERROR,
8574 "%s: ERROR !!!! Wireless dev is NULL", __func__);
8575 return -EINVAL;
8576 }
8577 goto done;
8578 }
8579
8580 default:
8581 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8582 __func__);
8583 return -EOPNOTSUPP;
8584 }
8585 }
8586 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008587 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008588 )
8589 {
8590 switch(type)
8591 {
8592 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008593 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008594 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05308595
8596 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308597#ifdef FEATURE_WLAN_TDLS
8598
8599 /* A Mutex Lock is introduced while changing the mode to
8600 * protect the concurrent access for the Adapters by TDLS
8601 * module.
8602 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308603 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308604#endif
c_hpothu002231a2015-02-05 14:58:51 +05308605 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008606 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008607 //Check for sub-string p2p to confirm its a p2p interface
8608 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008609 {
8610 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8611 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8612 }
8613 else
8614 {
8615 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008616 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008617 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008618 hdd_set_conparam(0);
8619 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008620 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
8621 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308622#ifdef FEATURE_WLAN_TDLS
8623 mutex_unlock(&pHddCtx->tdls_lock);
8624#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308625 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008626 if( VOS_STATUS_SUCCESS != status )
8627 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07008628 /* In case of JB, for P2P-GO, only change interface will be called,
8629 * This is the right place to enable back bmps_imps()
8630 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308631 if (pHddCtx->hdd_wlan_suspended)
8632 {
8633 hdd_set_pwrparams(pHddCtx);
8634 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008635 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008636 goto done;
8637 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008638 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008639 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008640 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8641 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008642 goto done;
8643 default:
8644 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8645 __func__);
8646 return -EOPNOTSUPP;
8647
8648 }
8649
8650 }
8651 else
8652 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308653 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
8654 __func__, hdd_device_modetoString(pAdapter->device_mode),
8655 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008656 return -EOPNOTSUPP;
8657 }
8658
8659
8660 if(pRoamProfile)
8661 {
8662 if ( LastBSSType != pRoamProfile->BSSType )
8663 {
8664 /*interface type changed update in wiphy structure*/
8665 wdev->iftype = type;
8666
8667 /*the BSS mode changed, We need to issue disconnect
8668 if connected or in IBSS disconnect state*/
8669 if ( hdd_connGetConnectedBssType(
8670 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
8671 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
8672 {
8673 /*need to issue a disconnect to CSR.*/
8674 INIT_COMPLETION(pAdapter->disconnect_comp_var);
8675 if( eHAL_STATUS_SUCCESS ==
8676 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
8677 pAdapter->sessionId,
8678 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
8679 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308680 ret = wait_for_completion_interruptible_timeout(
8681 &pAdapter->disconnect_comp_var,
8682 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
8683 if (ret <= 0)
8684 {
8685 hddLog(VOS_TRACE_LEVEL_ERROR,
8686 FL("wait on disconnect_comp_var failed %ld"), ret);
8687 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008688 }
8689 }
8690 }
8691 }
8692
8693done:
8694 /*set bitmask based on updated value*/
8695 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07008696
8697 /* Only STA mode support TM now
8698 * all other mode, TM feature should be disabled */
8699 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
8700 (~VOS_STA & pHddCtx->concurrency_mode) )
8701 {
8702 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
8703 }
8704
Jeff Johnson295189b2012-06-20 16:38:30 -07008705#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308706 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05308707 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07008708 {
8709 //we are ok to do AMP
8710 pHddCtx->isAmpAllowed = VOS_TRUE;
8711 }
8712#endif //WLAN_BTAMP_FEATURE
8713 EXIT();
8714 return 0;
8715}
8716
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308717/*
8718 * FUNCTION: wlan_hdd_cfg80211_change_iface
8719 * wrapper function to protect the actual implementation from SSR.
8720 */
8721int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
8722 struct net_device *ndev,
8723 enum nl80211_iftype type,
8724 u32 *flags,
8725 struct vif_params *params
8726 )
8727{
8728 int ret;
8729
8730 vos_ssr_protect(__func__);
8731 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
8732 vos_ssr_unprotect(__func__);
8733
8734 return ret;
8735}
8736
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008737#ifdef FEATURE_WLAN_TDLS
8738static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308739 struct net_device *dev,
8740#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
8741 const u8 *mac,
8742#else
8743 u8 *mac,
8744#endif
8745 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008746{
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008747 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008748 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308749 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308750 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308751 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05308752 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008753
8754 ENTER();
8755
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308756 if (!dev) {
8757 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
8758 return -EINVAL;
8759 }
8760
8761 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8762 if (!pAdapter) {
8763 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
8764 return -EINVAL;
8765 }
8766
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308767 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008768 {
8769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8770 "Invalid arguments");
8771 return -EINVAL;
8772 }
Hoonki Lee27511902013-03-14 18:19:06 -07008773
8774 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
8775 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
8776 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308777 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -07008778 "%s: TDLS mode is disabled OR not enabled in FW."
8779 MAC_ADDRESS_STR " Request declined.",
8780 __func__, MAC_ADDR_ARRAY(mac));
8781 return -ENOTSUPP;
8782 }
8783
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008784 if (pHddCtx->isLogpInProgress)
8785 {
8786 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8787 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05308788 wlan_hdd_tdls_set_link_status(pAdapter,
8789 mac,
8790 eTDLS_LINK_IDLE,
8791 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008792 return -EBUSY;
8793 }
8794
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308795 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05308796 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008797
8798 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008800 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
8801 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308802 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008803 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008804 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308805 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008806
8807 /* in add station, we accept existing valid staId if there is */
8808 if ((0 == update) &&
8809 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
8810 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008811 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308812 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008813 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008814 " link_status %d. staId %d. add station ignored.",
8815 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
8816 return 0;
8817 }
8818 /* in change station, we accept only when staId is valid */
8819 if ((1 == update) &&
8820 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
8821 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
8822 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308823 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008824 "%s: " MAC_ADDRESS_STR
8825 " link status %d. staId %d. change station %s.",
8826 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
8827 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
8828 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008829 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008830
8831 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +05308832 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008833 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008834 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8835 "%s: " MAC_ADDRESS_STR
8836 " TDLS setup is ongoing. Request declined.",
8837 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07008838 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008839 }
8840
8841 /* first to check if we reached to maximum supported TDLS peer.
8842 TODO: for now, return -EPERM looks working fine,
8843 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308844 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8845 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008846 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008847 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8848 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308849 " TDLS Max peer already connected. Request declined."
8850 " Num of peers (%d), Max allowed (%d).",
8851 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
8852 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008853 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008854 }
8855 else
8856 {
8857 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308858 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008859 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008860 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008861 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8862 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
8863 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008864 return -EPERM;
8865 }
8866 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008867 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05308868 wlan_hdd_tdls_set_link_status(pAdapter,
8869 mac,
8870 eTDLS_LINK_CONNECTING,
8871 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008872
Jeff Johnsond75fe012013-04-06 10:53:06 -07008873 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308874 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008875 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308876 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008877 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008878 if(StaParams->htcap_present)
8879 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308880 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008881 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308882 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008883 "ht_capa->extended_capabilities: %0x",
8884 StaParams->HTCap.extendedHtCapInfo);
8885 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308886 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008887 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308888 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008889 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008890 if(StaParams->vhtcap_present)
8891 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308892 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008893 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
8894 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
8895 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
8896 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008897 {
8898 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008899 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008900 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308901 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008902 "[%d]: %x ", i, StaParams->supported_rates[i]);
8903 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07008904 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308905 else if ((1 == update) && (NULL == StaParams))
8906 {
8907 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8908 "%s : update is true, but staParams is NULL. Error!", __func__);
8909 return -EPERM;
8910 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008911
8912 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
8913
8914 if (!update)
8915 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05308916 /*Before adding sta make sure that device exited from BMPS*/
8917 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
8918 {
8919 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8920 "%s: Adding tdls peer sta. Disable BMPS", __func__);
8921 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
8922 if (status != VOS_STATUS_SUCCESS) {
8923 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
8924 }
8925 }
8926
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308927 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008928 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308929 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05308930 hddLog(VOS_TRACE_LEVEL_ERROR,
8931 FL("Failed to add TDLS peer STA. Enable Bmps"));
8932 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308933 return -EPERM;
8934 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008935 }
8936 else
8937 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308938 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008939 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308940 if (ret != eHAL_STATUS_SUCCESS) {
8941 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
8942 return -EPERM;
8943 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008944 }
8945
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308946 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008947 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
8948
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308949 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008950 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008951 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308952 "%s: timeout waiting for tdls add station indication %ld",
8953 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008954 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008955 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308956
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008957 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
8958 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008959 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008960 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008961 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008962 }
8963
8964 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008965
8966error:
Atul Mittal115287b2014-07-08 13:26:33 +05308967 wlan_hdd_tdls_set_link_status(pAdapter,
8968 mac,
8969 eTDLS_LINK_IDLE,
8970 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008971 return -EPERM;
8972
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008973}
8974#endif
8975
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308976static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008977 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308978#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
8979 const u8 *mac,
8980#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008981 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308982#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008983 struct station_parameters *params)
8984{
8985 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308986 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308987 hdd_context_t *pHddCtx;
8988 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008989 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308990 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008991#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008992 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008993 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308994 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008995#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008996
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308997 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308998
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308999 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +05309000 if ((NULL == pAdapter))
9001 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309002 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309003 "invalid adapter ");
9004 return -EINVAL;
9005 }
9006
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309007 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9008 TRACE_CODE_HDD_CHANGE_STATION,
9009 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05309010 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05309011
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309012 ret = wlan_hdd_validate_context(pHddCtx);
9013 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05309014 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309015 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309016 }
9017
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309018 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9019
9020 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009021 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309022 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9023 "invalid HDD station context");
9024 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009025 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009026 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
9027
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009028 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
9029 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07009030 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009031 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07009032 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309033 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07009034 WLANTL_STA_AUTHENTICATED);
9035
Gopichand Nakkala29149562013-05-10 21:43:41 +05309036 if (status != VOS_STATUS_SUCCESS)
9037 {
9038 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9039 "%s: Not able to change TL state to AUTHENTICATED", __func__);
9040 return -EINVAL;
9041 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009042 }
9043 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07009044 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
9045 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309046#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009047 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
9048 StaParams.capability = params->capability;
9049 StaParams.uapsd_queues = params->uapsd_queues;
9050 StaParams.max_sp = params->max_sp;
9051
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309052 /* Convert (first channel , number of channels) tuple to
9053 * the total list of channels. This goes with the assumption
9054 * that if the first channel is < 14, then the next channels
9055 * are an incremental of 1 else an incremental of 4 till the number
9056 * of channels.
9057 */
9058 if (0 != params->supported_channels_len) {
9059 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
9060 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
9061 {
9062 int wifi_chan_index;
9063 StaParams.supported_channels[j] = params->supported_channels[i];
9064 wifi_chan_index =
9065 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
9066 no_of_channels = params->supported_channels[i+1];
9067 for(k=1; k <= no_of_channels; k++)
9068 {
9069 StaParams.supported_channels[j+1] =
9070 StaParams.supported_channels[j] + wifi_chan_index;
9071 j+=1;
9072 }
9073 }
9074 StaParams.supported_channels_len = j;
9075 }
9076 vos_mem_copy(StaParams.supported_oper_classes,
9077 params->supported_oper_classes,
9078 params->supported_oper_classes_len);
9079 StaParams.supported_oper_classes_len =
9080 params->supported_oper_classes_len;
9081
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009082 if (0 != params->ext_capab_len)
9083 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
9084 sizeof(StaParams.extn_capability));
9085
9086 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07009087 {
9088 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009089 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07009090 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009091
9092 StaParams.supported_rates_len = params->supported_rates_len;
9093
9094 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
9095 * The supported_rates array , for all the structures propogating till Add Sta
9096 * to the firmware has to be modified , if the supplicant (ieee80211) is
9097 * modified to send more rates.
9098 */
9099
9100 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
9101 */
9102 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
9103 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
9104
9105 if (0 != StaParams.supported_rates_len) {
9106 int i = 0;
9107 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
9108 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009109 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009110 "Supported Rates with Length %d", StaParams.supported_rates_len);
9111 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07009112 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009113 "[%d]: %0x", i, StaParams.supported_rates[i]);
9114 }
9115
9116 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07009117 {
9118 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009119 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07009120 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07009121
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009122 if (0 != params->ext_capab_len ) {
9123 /*Define A Macro : TODO Sunil*/
9124 if ((1<<4) & StaParams.extn_capability[3]) {
9125 isBufSta = 1;
9126 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309127 /* TDLS Channel Switching Support */
9128 if ((1<<6) & StaParams.extn_capability[3]) {
9129 isOffChannelSupported = 1;
9130 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009131 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05309132 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
9133 &StaParams, isBufSta,
9134 isOffChannelSupported);
9135
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05309136 if (VOS_STATUS_SUCCESS != status) {
9137 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9138 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
9139 return -EINVAL;
9140 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08009141 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
9142
9143 if (VOS_STATUS_SUCCESS != status) {
9144 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9145 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
9146 return -EINVAL;
9147 }
9148 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07009149#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05309150 }
Jeff Johnsone7245742012-09-05 17:12:55 -07009151 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009152 return status;
9153}
9154
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309155#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
9156static int wlan_hdd_change_station(struct wiphy *wiphy,
9157 struct net_device *dev,
9158 const u8 *mac,
9159 struct station_parameters *params)
9160#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309161static int wlan_hdd_change_station(struct wiphy *wiphy,
9162 struct net_device *dev,
9163 u8 *mac,
9164 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309165#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309166{
9167 int ret;
9168
9169 vos_ssr_protect(__func__);
9170 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
9171 vos_ssr_unprotect(__func__);
9172
9173 return ret;
9174}
9175
Jeff Johnson295189b2012-06-20 16:38:30 -07009176/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309177 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009178 * This function is used to initialize the key information
9179 */
9180#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309181static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009182 struct net_device *ndev,
9183 u8 key_index, bool pairwise,
9184 const u8 *mac_addr,
9185 struct key_params *params
9186 )
9187#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309188static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009189 struct net_device *ndev,
9190 u8 key_index, const u8 *mac_addr,
9191 struct key_params *params
9192 )
9193#endif
9194{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009195 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07009196 tCsrRoamSetKey setKey;
9197 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309198 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009199 v_U32_t roamId= 0xFF;
9200 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009201 hdd_hostapd_state_t *pHostapdState;
9202 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009203 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309204 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009205
9206 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309207
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309208 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9209 TRACE_CODE_HDD_CFG80211_ADD_KEY,
9210 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309211 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9212 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309213 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009214 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309215 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009216 }
9217
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309218 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9219 __func__, hdd_device_modetoString(pAdapter->device_mode),
9220 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009221
9222 if (CSR_MAX_NUM_KEY <= key_index)
9223 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009224 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009225 key_index);
9226
9227 return -EINVAL;
9228 }
9229
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009230 if (CSR_MAX_KEY_LEN < params->key_len)
9231 {
9232 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
9233 params->key_len);
9234
9235 return -EINVAL;
9236 }
9237
9238 hddLog(VOS_TRACE_LEVEL_INFO,
9239 "%s: called with key index = %d & key length %d",
9240 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009241
9242 /*extract key idx, key len and key*/
9243 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9244 setKey.keyId = key_index;
9245 setKey.keyLength = params->key_len;
9246 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
9247
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009248 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009249 {
9250 case WLAN_CIPHER_SUITE_WEP40:
9251 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
9252 break;
9253
9254 case WLAN_CIPHER_SUITE_WEP104:
9255 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
9256 break;
9257
9258 case WLAN_CIPHER_SUITE_TKIP:
9259 {
9260 u8 *pKey = &setKey.Key[0];
9261 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
9262
9263 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
9264
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009265 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07009266
9267 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009268 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009269 |--------------|----------|----------|
9270 <---16bytes---><--8bytes--><--8bytes-->
9271
9272 */
9273 /*Sme expects the 32 bytes key to be in the below order
9274
9275 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009276 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009277 |--------------|----------|----------|
9278 <---16bytes---><--8bytes--><--8bytes-->
9279 */
9280 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009281 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07009282
9283 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009284 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009285
9286 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009287 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009288
9289
9290 break;
9291 }
9292
9293 case WLAN_CIPHER_SUITE_CCMP:
9294 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
9295 break;
9296
9297#ifdef FEATURE_WLAN_WAPI
9298 case WLAN_CIPHER_SUITE_SMS4:
9299 {
9300 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9301 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
9302 params->key, params->key_len);
9303 return 0;
9304 }
9305#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009306
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009307#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009308 case WLAN_CIPHER_SUITE_KRK:
9309 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
9310 break;
9311#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009312
9313#ifdef WLAN_FEATURE_11W
9314 case WLAN_CIPHER_SUITE_AES_CMAC:
9315 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07009316 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07009317#endif
9318
Jeff Johnson295189b2012-06-20 16:38:30 -07009319 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009320 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009321 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309322 status = -EOPNOTSUPP;
9323 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009324 }
9325
9326 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
9327 __func__, setKey.encType);
9328
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009329 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07009330#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9331 (!pairwise)
9332#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009333 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07009334#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009335 )
9336 {
9337 /* set group key*/
9338 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9339 "%s- %d: setting Broadcast key",
9340 __func__, __LINE__);
9341 setKey.keyDirection = eSIR_RX_ONLY;
9342 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9343 }
9344 else
9345 {
9346 /* set pairwise key*/
9347 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9348 "%s- %d: setting pairwise key",
9349 __func__, __LINE__);
9350 setKey.keyDirection = eSIR_TX_RX;
9351 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9352 }
9353 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
9354 {
9355 setKey.keyDirection = eSIR_TX_RX;
9356 /*Set the group key*/
9357 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9358 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07009359
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009360 if ( 0 != status )
9361 {
9362 hddLog(VOS_TRACE_LEVEL_ERROR,
9363 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309364 status = -EINVAL;
9365 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009366 }
9367 /*Save the keys here and call sme_RoamSetKey for setting
9368 the PTK after peer joins the IBSS network*/
9369 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
9370 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309371 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009372 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05309373 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
9374 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
9375 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009376 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009377 if( pHostapdState->bssState == BSS_START )
9378 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009379 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9380 vos_status = wlan_hdd_check_ula_done(pAdapter);
9381
9382 if ( vos_status != VOS_STATUS_SUCCESS )
9383 {
9384 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9385 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9386 __LINE__, vos_status );
9387
9388 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9389
9390 status = -EINVAL;
9391 goto end;
9392 }
9393
Jeff Johnson295189b2012-06-20 16:38:30 -07009394 status = WLANSAP_SetKeySta( pVosContext, &setKey);
9395
9396 if ( status != eHAL_STATUS_SUCCESS )
9397 {
9398 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9399 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9400 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309401 status = -EINVAL;
9402 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009403 }
9404 }
9405
9406 /* Saving WEP keys */
9407 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
9408 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
9409 {
9410 //Save the wep key in ap context. Issue setkey after the BSS is started.
9411 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9412 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
9413 }
9414 else
9415 {
9416 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009417 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009418 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
9419 }
9420 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009421 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
9422 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009423 {
9424 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9425 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9426
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309427#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9428 if (!pairwise)
9429#else
9430 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9431#endif
9432 {
9433 /* set group key*/
9434 if (pHddStaCtx->roam_info.deferKeyComplete)
9435 {
9436 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9437 "%s- %d: Perform Set key Complete",
9438 __func__, __LINE__);
9439 hdd_PerformRoamSetKeyComplete(pAdapter);
9440 }
9441 }
9442
Jeff Johnson295189b2012-06-20 16:38:30 -07009443 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
9444
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08009445 pWextState->roamProfile.Keys.defaultIndex = key_index;
9446
9447
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009448 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009449 params->key, params->key_len);
9450
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309451
Jeff Johnson295189b2012-06-20 16:38:30 -07009452 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9453
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309454 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009455 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309456 __func__, setKey.peerMac[0], setKey.peerMac[1],
9457 setKey.peerMac[2], setKey.peerMac[3],
9458 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009459 setKey.keyDirection);
9460
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009461 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +05309462
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009463 if ( vos_status != VOS_STATUS_SUCCESS )
9464 {
9465 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009466 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9467 __LINE__, vos_status );
9468
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009469 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009470
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009471 status = -EINVAL;
9472 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009473
9474 }
9475
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009476#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309477 /* The supplicant may attempt to set the PTK once pre-authentication
9478 is done. Save the key in the UMAC and include it in the ADD BSS
9479 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009480 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309481 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009482 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309483 hddLog(VOS_TRACE_LEVEL_INFO_MED,
9484 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309485 status = 0;
9486 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309487 }
9488 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
9489 {
9490 hddLog(VOS_TRACE_LEVEL_ERROR,
9491 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309492 status = -EINVAL;
9493 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009494 }
9495#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07009496
9497 /* issue set key request to SME*/
9498 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9499 pAdapter->sessionId, &setKey, &roamId );
9500
9501 if ( 0 != status )
9502 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309503 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009504 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
9505 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309506 status = -EINVAL;
9507 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009508 }
9509
9510
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309511 /* in case of IBSS as there was no information available about WEP keys during
9512 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07009513 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309514 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
9515 !( ( IW_AUTH_KEY_MGMT_802_1X
9516 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07009517 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
9518 )
9519 &&
9520 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
9521 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
9522 )
9523 )
9524 {
9525 setKey.keyDirection = eSIR_RX_ONLY;
9526 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9527
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309528 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009529 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309530 __func__, setKey.peerMac[0], setKey.peerMac[1],
9531 setKey.peerMac[2], setKey.peerMac[3],
9532 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009533 setKey.keyDirection);
9534
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309535 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009536 pAdapter->sessionId, &setKey, &roamId );
9537
9538 if ( 0 != status )
9539 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309540 hddLog(VOS_TRACE_LEVEL_ERROR,
9541 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009542 __func__, status);
9543 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309544 status = -EINVAL;
9545 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009546 }
9547 }
9548 }
9549
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309550end:
9551 /* Need to clear any trace of key value in the memory.
9552 * Thus zero out the memory even though it is local
9553 * variable.
9554 */
9555 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309556 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309557 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009558}
9559
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309560#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9561static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9562 struct net_device *ndev,
9563 u8 key_index, bool pairwise,
9564 const u8 *mac_addr,
9565 struct key_params *params
9566 )
9567#else
9568static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9569 struct net_device *ndev,
9570 u8 key_index, const u8 *mac_addr,
9571 struct key_params *params
9572 )
9573#endif
9574{
9575 int ret;
9576 vos_ssr_protect(__func__);
9577#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9578 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
9579 mac_addr, params);
9580#else
9581 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
9582 params);
9583#endif
9584 vos_ssr_unprotect(__func__);
9585
9586 return ret;
9587}
9588
Jeff Johnson295189b2012-06-20 16:38:30 -07009589/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309590 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009591 * This function is used to get the key information
9592 */
9593#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309594static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309595 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009596 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309597 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009598 const u8 *mac_addr, void *cookie,
9599 void (*callback)(void *cookie, struct key_params*)
9600 )
9601#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309602static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309603 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009604 struct net_device *ndev,
9605 u8 key_index, const u8 *mac_addr, void *cookie,
9606 void (*callback)(void *cookie, struct key_params*)
9607 )
9608#endif
9609{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309610 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309611 hdd_wext_state_t *pWextState = NULL;
9612 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009613 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309614 hdd_context_t *pHddCtx;
9615 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009616
9617 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309618
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309619 if (NULL == pAdapter)
9620 {
9621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9622 "%s: HDD adapter is Null", __func__);
9623 return -ENODEV;
9624 }
9625
9626 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9627 ret = wlan_hdd_validate_context(pHddCtx);
9628 if (0 != ret)
9629 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309630 return ret;
9631 }
9632
9633 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9634 pRoamProfile = &(pWextState->roamProfile);
9635
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309636 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9637 __func__, hdd_device_modetoString(pAdapter->device_mode),
9638 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309639
Jeff Johnson295189b2012-06-20 16:38:30 -07009640 memset(&params, 0, sizeof(params));
9641
9642 if (CSR_MAX_NUM_KEY <= key_index)
9643 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309644 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07009645 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309646 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009647
9648 switch(pRoamProfile->EncryptionType.encryptionType[0])
9649 {
9650 case eCSR_ENCRYPT_TYPE_NONE:
9651 params.cipher = IW_AUTH_CIPHER_NONE;
9652 break;
9653
9654 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
9655 case eCSR_ENCRYPT_TYPE_WEP40:
9656 params.cipher = WLAN_CIPHER_SUITE_WEP40;
9657 break;
9658
9659 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
9660 case eCSR_ENCRYPT_TYPE_WEP104:
9661 params.cipher = WLAN_CIPHER_SUITE_WEP104;
9662 break;
9663
9664 case eCSR_ENCRYPT_TYPE_TKIP:
9665 params.cipher = WLAN_CIPHER_SUITE_TKIP;
9666 break;
9667
9668 case eCSR_ENCRYPT_TYPE_AES:
9669 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
9670 break;
9671
9672 default:
9673 params.cipher = IW_AUTH_CIPHER_NONE;
9674 break;
9675 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309676
c_hpothuaaf19692014-05-17 17:01:48 +05309677 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9678 TRACE_CODE_HDD_CFG80211_GET_KEY,
9679 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309680
Jeff Johnson295189b2012-06-20 16:38:30 -07009681 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
9682 params.seq_len = 0;
9683 params.seq = NULL;
9684 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
9685 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309686 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009687 return 0;
9688}
9689
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309690#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9691static int wlan_hdd_cfg80211_get_key(
9692 struct wiphy *wiphy,
9693 struct net_device *ndev,
9694 u8 key_index, bool pairwise,
9695 const u8 *mac_addr, void *cookie,
9696 void (*callback)(void *cookie, struct key_params*)
9697 )
9698#else
9699static int wlan_hdd_cfg80211_get_key(
9700 struct wiphy *wiphy,
9701 struct net_device *ndev,
9702 u8 key_index, const u8 *mac_addr, void *cookie,
9703 void (*callback)(void *cookie, struct key_params*)
9704 )
9705#endif
9706{
9707 int ret;
9708
9709 vos_ssr_protect(__func__);
9710#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9711 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
9712 mac_addr, cookie, callback);
9713#else
9714 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
9715 callback);
9716#endif
9717 vos_ssr_unprotect(__func__);
9718
9719 return ret;
9720}
9721
Jeff Johnson295189b2012-06-20 16:38:30 -07009722/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309723 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009724 * This function is used to delete the key information
9725 */
9726#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309727static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009728 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309729 u8 key_index,
9730 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009731 const u8 *mac_addr
9732 )
9733#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309734static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009735 struct net_device *ndev,
9736 u8 key_index,
9737 const u8 *mac_addr
9738 )
9739#endif
9740{
9741 int status = 0;
9742
9743 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309744 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07009745 //it is observed that this is invalidating peer
9746 //key index whenever re-key is done. This is affecting data link.
9747 //It should be ok to ignore del_key.
9748#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309749 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
9750 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009751 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
9752 tCsrRoamSetKey setKey;
9753 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309754
Jeff Johnson295189b2012-06-20 16:38:30 -07009755 ENTER();
9756
9757 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
9758 __func__,pAdapter->device_mode);
9759
9760 if (CSR_MAX_NUM_KEY <= key_index)
9761 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309762 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009763 key_index);
9764
9765 return -EINVAL;
9766 }
9767
9768 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9769 setKey.keyId = key_index;
9770
9771 if (mac_addr)
9772 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9773 else
9774 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
9775
9776 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
9777
9778 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009779 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309780 )
9781 {
9782
9783 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07009784 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9785 if( pHostapdState->bssState == BSS_START)
9786 {
9787 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309788
Jeff Johnson295189b2012-06-20 16:38:30 -07009789 if ( status != eHAL_STATUS_SUCCESS )
9790 {
9791 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9792 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9793 __LINE__, status );
9794 }
9795 }
9796 }
9797 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309798 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07009799 )
9800 {
9801 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9802
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309803 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9804
9805 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009806 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309807 __func__, setKey.peerMac[0], setKey.peerMac[1],
9808 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07009809 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309810 if(pAdapter->sessionCtx.station.conn_info.connState ==
9811 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07009812 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309813 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009814 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309815
Jeff Johnson295189b2012-06-20 16:38:30 -07009816 if ( 0 != status )
9817 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309818 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009819 "%s: sme_RoamSetKey failure, returned %d",
9820 __func__, status);
9821 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9822 return -EINVAL;
9823 }
9824 }
9825 }
9826#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009827 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009828 return status;
9829}
9830
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309831#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9832static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9833 struct net_device *ndev,
9834 u8 key_index,
9835 bool pairwise,
9836 const u8 *mac_addr
9837 )
9838#else
9839static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9840 struct net_device *ndev,
9841 u8 key_index,
9842 const u8 *mac_addr
9843 )
9844#endif
9845{
9846 int ret;
9847
9848 vos_ssr_protect(__func__);
9849#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9850 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
9851 mac_addr);
9852#else
9853 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
9854#endif
9855 vos_ssr_unprotect(__func__);
9856
9857 return ret;
9858}
9859
Jeff Johnson295189b2012-06-20 16:38:30 -07009860/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309861 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009862 * This function is used to set the default tx key index
9863 */
9864#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309865static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009866 struct net_device *ndev,
9867 u8 key_index,
9868 bool unicast, bool multicast)
9869#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309870static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009871 struct net_device *ndev,
9872 u8 key_index)
9873#endif
9874{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309875 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309876 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309877 hdd_wext_state_t *pWextState;
9878 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309879 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009880
9881 ENTER();
9882
Gopichand Nakkala29149562013-05-10 21:43:41 +05309883 if ((NULL == pAdapter))
9884 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309885 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309886 "invalid adapter");
9887 return -EINVAL;
9888 }
9889
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309890 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9891 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
9892 pAdapter->sessionId, key_index));
9893
Gopichand Nakkala29149562013-05-10 21:43:41 +05309894 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9895 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9896
9897 if ((NULL == pWextState) || (NULL == pHddStaCtx))
9898 {
9899 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9900 "invalid Wext state or HDD context");
9901 return -EINVAL;
9902 }
9903
Arif Hussain6d2a3322013-11-17 19:50:10 -08009904 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009905 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309906
Jeff Johnson295189b2012-06-20 16:38:30 -07009907 if (CSR_MAX_NUM_KEY <= key_index)
9908 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309909 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009910 key_index);
9911
9912 return -EINVAL;
9913 }
9914
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309915 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9916 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309917 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009918 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309919 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009920 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309921
Jeff Johnson295189b2012-06-20 16:38:30 -07009922 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07009923 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309924 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009925 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309926 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08009927 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309928 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08009929 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07009930 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309931 {
9932 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07009933 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309934
Jeff Johnson295189b2012-06-20 16:38:30 -07009935 tCsrRoamSetKey setKey;
9936 v_U32_t roamId= 0xFF;
9937 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309938
9939 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009940 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309941
Jeff Johnson295189b2012-06-20 16:38:30 -07009942 Keys->defaultIndex = (u8)key_index;
9943 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9944 setKey.keyId = key_index;
9945 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309946
9947 vos_mem_copy(&setKey.Key[0],
9948 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009949 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309950
Gopichand Nakkala29149562013-05-10 21:43:41 +05309951 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309952
9953 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07009954 &pHddStaCtx->conn_info.bssId[0],
9955 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309956
Gopichand Nakkala29149562013-05-10 21:43:41 +05309957 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
9958 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
9959 eCSR_ENCRYPT_TYPE_WEP104)
9960 {
9961 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
9962 even though ap is configured for WEP-40 encryption. In this canse the key length
9963 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
9964 type(104) and switching encryption type to 40*/
9965 pWextState->roamProfile.EncryptionType.encryptionType[0] =
9966 eCSR_ENCRYPT_TYPE_WEP40;
9967 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
9968 eCSR_ENCRYPT_TYPE_WEP40;
9969 }
9970
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309971 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07009972 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309973
Jeff Johnson295189b2012-06-20 16:38:30 -07009974 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309975 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009976 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309977
Jeff Johnson295189b2012-06-20 16:38:30 -07009978 if ( 0 != status )
9979 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309980 hddLog(VOS_TRACE_LEVEL_ERROR,
9981 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009982 status);
9983 return -EINVAL;
9984 }
9985 }
9986 }
9987
9988 /* In SoftAp mode setting key direction for default mode */
9989 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
9990 {
9991 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
9992 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
9993 (eCSR_ENCRYPT_TYPE_AES !=
9994 pWextState->roamProfile.EncryptionType.encryptionType[0])
9995 )
9996 {
9997 /* Saving key direction for default key index to TX default */
9998 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9999 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
10000 }
10001 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010002 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070010003 return status;
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_set_default_key( struct wiphy *wiphy,
10008 struct net_device *ndev,
10009 u8 key_index,
10010 bool unicast, bool multicast)
10011#else
10012static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
10013 struct net_device *ndev,
10014 u8 key_index)
10015#endif
10016{
10017 int ret;
10018 vos_ssr_protect(__func__);
10019#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
10020 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
10021 multicast);
10022#else
10023 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
10024#endif
10025 vos_ssr_unprotect(__func__);
10026
10027 return ret;
10028}
10029
Jeff Johnson295189b2012-06-20 16:38:30 -070010030/*
10031 * FUNCTION: wlan_hdd_cfg80211_inform_bss
10032 * This function is used to inform the BSS details to nl80211 interface.
10033 */
10034static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
10035 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
10036{
10037 struct net_device *dev = pAdapter->dev;
10038 struct wireless_dev *wdev = dev->ieee80211_ptr;
10039 struct wiphy *wiphy = wdev->wiphy;
10040 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
10041 int chan_no;
10042 int ie_length;
10043 const char *ie;
10044 unsigned int freq;
10045 struct ieee80211_channel *chan;
10046 int rssi = 0;
10047 struct cfg80211_bss *bss = NULL;
10048
Jeff Johnson295189b2012-06-20 16:38:30 -070010049 if( NULL == pBssDesc )
10050 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010051 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010052 return bss;
10053 }
10054
10055 chan_no = pBssDesc->channelId;
10056 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
10057 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
10058
10059 if( NULL == ie )
10060 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010061 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010062 return bss;
10063 }
10064
10065#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
10066 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
10067 {
10068 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10069 }
10070 else
10071 {
10072 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10073 }
10074#else
10075 freq = ieee80211_channel_to_frequency(chan_no);
10076#endif
10077
10078 chan = __ieee80211_get_channel(wiphy, freq);
10079
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +053010080 if (!chan) {
10081 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
10082 return NULL;
10083 }
10084
Abhishek Singhaee43942014-06-16 18:55:47 +053010085 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -070010086
Anand N Sunkad9f80b742015-07-30 20:05:51 +053010087 return cfg80211_inform_bss(wiphy, chan,
10088#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
10089 CFG80211_BSS_FTYPE_UNKNOWN,
10090#endif
10091 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010092 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -070010093 pBssDesc->capabilityInfo,
10094 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +053010095 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -070010096}
10097
10098
10099
10100/*
10101 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
10102 * This function is used to inform the BSS details to nl80211 interface.
10103 */
10104struct cfg80211_bss*
10105wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
10106 tSirBssDescription *bss_desc
10107 )
10108{
10109 /*
10110 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
10111 already exists in bss data base of cfg80211 for that particular BSS ID.
10112 Using cfg80211_inform_bss_frame to update the bss entry instead of
10113 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
10114 now there is no possibility to get the mgmt(probe response) frame from PE,
10115 converting bss_desc to ieee80211_mgmt(probe response) and passing to
10116 cfg80211_inform_bss_frame.
10117 */
10118 struct net_device *dev = pAdapter->dev;
10119 struct wireless_dev *wdev = dev->ieee80211_ptr;
10120 struct wiphy *wiphy = wdev->wiphy;
10121 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010122#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
10123 qcom_ie_age *qie_age = NULL;
10124 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
10125#else
Jeff Johnson295189b2012-06-20 16:38:30 -070010126 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010127#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010128 const char *ie =
10129 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
10130 unsigned int freq;
10131 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053010132 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010133 struct cfg80211_bss *bss_status = NULL;
10134 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
10135 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -070010136 hdd_context_t *pHddCtx;
10137 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -070010138#ifdef WLAN_OPEN_SOURCE
10139 struct timespec ts;
10140#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070010141
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053010142
Wilson Yangf80a0542013-10-07 13:02:37 -070010143 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10144 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -070010145 if (0 != status)
10146 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070010147 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010148 }
10149
Abhishek Singh1e2bfa32014-01-02 15:44:15 +053010150 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -070010151 if (!mgmt)
10152 {
10153 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10154 "%s: memory allocation failed ", __func__);
10155 return NULL;
10156 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070010157
Jeff Johnson295189b2012-06-20 16:38:30 -070010158 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070010159
10160#ifdef WLAN_OPEN_SOURCE
10161 /* Android does not want the timestamp from the frame.
10162 Instead it wants a monotonic increasing value */
10163 get_monotonic_boottime(&ts);
10164 mgmt->u.probe_resp.timestamp =
10165 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
10166#else
10167 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070010168 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
10169 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070010170
10171#endif
10172
Jeff Johnson295189b2012-06-20 16:38:30 -070010173 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
10174 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010175
10176#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
10177 /* GPS Requirement: need age ie per entry. Using vendor specific. */
10178 /* Assuming this is the last IE, copy at the end */
10179 ie_length -=sizeof(qcom_ie_age);
10180 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
10181 qie_age->element_id = QCOM_VENDOR_IE_ID;
10182 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
10183 qie_age->oui_1 = QCOM_OUI1;
10184 qie_age->oui_2 = QCOM_OUI2;
10185 qie_age->oui_3 = QCOM_OUI3;
10186 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
10187 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
10188#endif
10189
Jeff Johnson295189b2012-06-20 16:38:30 -070010190 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053010191 if (bss_desc->fProbeRsp)
10192 {
10193 mgmt->frame_control |=
10194 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
10195 }
10196 else
10197 {
10198 mgmt->frame_control |=
10199 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
10200 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010201
10202#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010203 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010204 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
10205 {
10206 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10207 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010208 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010209 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
10210
10211 {
10212 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10213 }
10214 else
10215 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010216 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
10217 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070010218 kfree(mgmt);
10219 return NULL;
10220 }
10221#else
10222 freq = ieee80211_channel_to_frequency(chan_no);
10223#endif
10224 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010225 /*when the band is changed on the fly using the GUI, three things are done
10226 * 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)
10227 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
10228 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
10229 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
10230 * and discards the channels correponding to previous band and calls back with zero bss results.
10231 * 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
10232 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
10233 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
10234 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
10235 * So drop the bss and continue to next bss.
10236 */
10237 if(chan == NULL)
10238 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010239 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070010240 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010241 return NULL;
10242 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053010243 /*To keep the rssi icon of the connected AP in the scan window
10244 *and the rssi icon of the wireless networks in sync
10245 * */
10246 if (( eConnectionState_Associated ==
10247 pAdapter->sessionCtx.station.conn_info.connState ) &&
10248 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
10249 pAdapter->sessionCtx.station.conn_info.bssId,
10250 WNI_CFG_BSSID_LEN)) &&
10251 (pHddCtx->hdd_wlan_suspended == FALSE))
10252 {
10253 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
10254 rssi = (pAdapter->rssi * 100);
10255 }
10256 else
10257 {
10258 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
10259 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010260
Nirav Shah20ac06f2013-12-12 18:14:06 +053010261 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053010262 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
10263 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053010264
Jeff Johnson295189b2012-06-20 16:38:30 -070010265 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
10266 frame_len, rssi, GFP_KERNEL);
10267 kfree(mgmt);
10268 return bss_status;
10269}
10270
10271/*
10272 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
10273 * This function is used to update the BSS data base of CFG8011
10274 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010275struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010276 tCsrRoamInfo *pRoamInfo
10277 )
10278{
10279 tCsrRoamConnectedProfile roamProfile;
10280 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10281 struct cfg80211_bss *bss = NULL;
10282
10283 ENTER();
10284
10285 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
10286 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
10287
10288 if (NULL != roamProfile.pBssDesc)
10289 {
Girish Gowlif4b68022014-08-28 23:18:57 +053010290 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10291 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070010292
10293 if (NULL == bss)
10294 {
10295 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
10296 __func__);
10297 }
10298
10299 sme_RoamFreeConnectProfile(hHal, &roamProfile);
10300 }
10301 else
10302 {
10303 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
10304 __func__);
10305 }
10306 return bss;
10307}
10308
10309/*
10310 * FUNCTION: wlan_hdd_cfg80211_update_bss
10311 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010312static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
10313 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070010314 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010315{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010316 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010317 tCsrScanResultInfo *pScanResult;
10318 eHalStatus status = 0;
10319 tScanResultHandle pResult;
10320 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010321 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010322 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070010323 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010324
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010325 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10326 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
10327 NO_SESSION, pAdapter->sessionId));
10328
Wilson Yangf80a0542013-10-07 13:02:37 -070010329 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10330
10331 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070010332 {
Wilson Yangf80a0542013-10-07 13:02:37 -070010333 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10334 "%s:LOGP in Progress. Ignore!!!",__func__);
10335 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010336 }
10337
Wilson Yangf80a0542013-10-07 13:02:37 -070010338
10339 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053010340 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070010341 {
10342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10343 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
10344 return VOS_STATUS_E_PERM;
10345 }
10346
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010347 if (pAdapter->request != NULL)
10348 {
10349 if ((pAdapter->request->n_ssids == 1)
10350 && (pAdapter->request->ssids != NULL)
10351 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
10352 is_p2p_scan = true;
10353 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010354 /*
10355 * start getting scan results and populate cgf80211 BSS database
10356 */
10357 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
10358
10359 /* no scan results */
10360 if (NULL == pResult)
10361 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010362 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
10363 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053010364 wlan_hdd_get_frame_logs(pAdapter,
10365 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070010366 return status;
10367 }
10368
10369 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
10370
10371 while (pScanResult)
10372 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010373 /*
10374 * cfg80211_inform_bss() is not updating ie field of bss entry, if
10375 * entry already exists in bss data base of cfg80211 for that
10376 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
10377 * bss entry instead of cfg80211_inform_bss, But this call expects
10378 * mgmt packet as input. As of now there is no possibility to get
10379 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070010380 * ieee80211_mgmt(probe response) and passing to c
10381 * fg80211_inform_bss_frame.
10382 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010383 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
10384 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
10385 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010386 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10387 continue; //Skip the non p2p bss entries
10388 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010389 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10390 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010391
Jeff Johnson295189b2012-06-20 16:38:30 -070010392
10393 if (NULL == bss_status)
10394 {
10395 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010396 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010397 }
10398 else
10399 {
Yue Maf49ba872013-08-19 12:04:25 -070010400 cfg80211_put_bss(
10401#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
10402 wiphy,
10403#endif
10404 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010405 }
10406
10407 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10408 }
10409
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010410 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010411 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010412 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010413}
10414
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010415void
10416hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
10417{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010418 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080010419 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010420} /****** end hddPrintMacAddr() ******/
10421
10422void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010423hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010424{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010425 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010426 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010427 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
10428 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
10429 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010430} /****** end hddPrintPmkId() ******/
10431
10432//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
10433//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
10434
10435//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
10436//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
10437
10438#define dump_bssid(bssid) \
10439 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010440 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
10441 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010442 }
10443
10444#define dump_pmkid(pMac, pmkid) \
10445 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010446 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
10447 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010448 }
10449
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070010450#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010451/*
10452 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
10453 * This function is used to notify the supplicant of a new PMKSA candidate.
10454 */
10455int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010456 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010457 int index, bool preauth )
10458{
Jeff Johnsone7245742012-09-05 17:12:55 -070010459#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010460 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010461 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010462
10463 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070010464 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010465
10466 if( NULL == pRoamInfo )
10467 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010468 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010469 return -EINVAL;
10470 }
10471
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010472 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
10473 {
10474 dump_bssid(pRoamInfo->bssid);
10475 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010476 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010477 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010478#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010479 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010480}
10481#endif //FEATURE_WLAN_LFR
10482
Yue Maef608272013-04-08 23:09:17 -070010483#ifdef FEATURE_WLAN_LFR_METRICS
10484/*
10485 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
10486 * 802.11r/LFR metrics reporting function to report preauth initiation
10487 *
10488 */
10489#define MAX_LFR_METRICS_EVENT_LENGTH 100
10490VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
10491 tCsrRoamInfo *pRoamInfo)
10492{
10493 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10494 union iwreq_data wrqu;
10495
10496 ENTER();
10497
10498 if (NULL == pAdapter)
10499 {
10500 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10501 return VOS_STATUS_E_FAILURE;
10502 }
10503
10504 /* create the event */
10505 memset(&wrqu, 0, sizeof(wrqu));
10506 memset(metrics_notification, 0, sizeof(metrics_notification));
10507
10508 wrqu.data.pointer = metrics_notification;
10509 wrqu.data.length = scnprintf(metrics_notification,
10510 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
10511 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10512
10513 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10514
10515 EXIT();
10516
10517 return VOS_STATUS_SUCCESS;
10518}
10519
10520/*
10521 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
10522 * 802.11r/LFR metrics reporting function to report preauth completion
10523 * or failure
10524 */
10525VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
10526 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
10527{
10528 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10529 union iwreq_data wrqu;
10530
10531 ENTER();
10532
10533 if (NULL == pAdapter)
10534 {
10535 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10536 return VOS_STATUS_E_FAILURE;
10537 }
10538
10539 /* create the event */
10540 memset(&wrqu, 0, sizeof(wrqu));
10541 memset(metrics_notification, 0, sizeof(metrics_notification));
10542
10543 scnprintf(metrics_notification, sizeof(metrics_notification),
10544 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
10545 MAC_ADDR_ARRAY(pRoamInfo->bssid));
10546
10547 if (1 == preauth_status)
10548 strncat(metrics_notification, " TRUE", 5);
10549 else
10550 strncat(metrics_notification, " FALSE", 6);
10551
10552 wrqu.data.pointer = metrics_notification;
10553 wrqu.data.length = strlen(metrics_notification);
10554
10555 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10556
10557 EXIT();
10558
10559 return VOS_STATUS_SUCCESS;
10560}
10561
10562/*
10563 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
10564 * 802.11r/LFR metrics reporting function to report handover initiation
10565 *
10566 */
10567VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
10568 tCsrRoamInfo *pRoamInfo)
10569{
10570 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10571 union iwreq_data wrqu;
10572
10573 ENTER();
10574
10575 if (NULL == pAdapter)
10576 {
10577 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10578 return VOS_STATUS_E_FAILURE;
10579 }
10580
10581 /* create the event */
10582 memset(&wrqu, 0, sizeof(wrqu));
10583 memset(metrics_notification, 0, sizeof(metrics_notification));
10584
10585 wrqu.data.pointer = metrics_notification;
10586 wrqu.data.length = scnprintf(metrics_notification,
10587 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
10588 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10589
10590 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10591
10592 EXIT();
10593
10594 return VOS_STATUS_SUCCESS;
10595}
10596#endif
10597
Jeff Johnson295189b2012-06-20 16:38:30 -070010598/*
10599 * FUNCTION: hdd_cfg80211_scan_done_callback
10600 * scanning callback function, called after finishing scan
10601 *
10602 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010603static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070010604 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
10605{
10606 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010607 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070010608 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010609 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010610 struct cfg80211_scan_request *req = NULL;
10611 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010612 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010613 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010614 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010615 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010616
10617 ENTER();
10618
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010619 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053010620 if (NULL == pHddCtx) {
10621 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010622 goto allow_suspend;
10623 }
10624
10625 pScanInfo = &pHddCtx->scan_info;
10626
Jeff Johnson295189b2012-06-20 16:38:30 -070010627 hddLog(VOS_TRACE_LEVEL_INFO,
10628 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080010629 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010630 __func__, halHandle, pContext, (int) scanId, (int) status);
10631
Kiet Lamac06e2c2013-10-23 16:25:07 +053010632 pScanInfo->mScanPendingCounter = 0;
10633
Jeff Johnson295189b2012-06-20 16:38:30 -070010634 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010635 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070010636 &pScanInfo->scan_req_completion_event,
10637 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010638 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070010639 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010640 hddLog(VOS_TRACE_LEVEL_ERROR,
10641 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070010642 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010643 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010644 }
10645
Yue Maef608272013-04-08 23:09:17 -070010646 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010647 {
10648 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010649 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010650 }
10651
10652 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010653 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070010654 {
10655 hddLog(VOS_TRACE_LEVEL_INFO,
10656 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010657 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070010658 (int) scanId);
10659 }
10660
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010661 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010662 pAdapter);
10663
10664 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010665 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010666
10667
10668 /* If any client wait scan result through WEXT
10669 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010670 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070010671 {
10672 /* The other scan request waiting for current scan finish
10673 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010674 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010675 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010676 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070010677 }
10678 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010679 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010680 {
10681 struct net_device *dev = pAdapter->dev;
10682 union iwreq_data wrqu;
10683 int we_event;
10684 char *msg;
10685
10686 memset(&wrqu, '\0', sizeof(wrqu));
10687 we_event = SIOCGIWSCAN;
10688 msg = NULL;
10689 wireless_send_event(dev, we_event, &wrqu, msg);
10690 }
10691 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010692 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010693
10694 /* Get the Scan Req */
10695 req = pAdapter->request;
10696
10697 if (!req)
10698 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010699 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010700 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010701 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010702 }
10703
Jeff Johnson295189b2012-06-20 16:38:30 -070010704 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070010705 /* Scan is no longer pending */
10706 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010707
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010708 /* last_scan_timestamp is used to decide if new scan
10709 * is needed or not on station interface. If last station
10710 * scan time and new station scan time is less then
10711 * last_scan_timestamp ; driver will return cached scan.
10712 */
10713 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
10714 {
10715 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
10716
10717 if ( req->n_channels )
10718 {
10719 for (i = 0; i < req->n_channels ; i++ )
10720 {
10721 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
10722 }
10723 /* store no of channel scanned */
10724 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
10725 }
10726
10727 }
10728
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070010729 /*
10730 * cfg80211_scan_done informing NL80211 about completion
10731 * of scanning
10732 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010733 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
10734 {
10735 aborted = true;
10736 }
10737 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080010738 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010739
Siddharth Bhal76972212014-10-15 16:22:51 +053010740 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
10741 /* Generate new random mac addr for next scan */
10742 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
10743 hdd_processSpoofMacAddrRequest(pHddCtx);
10744 }
10745
Jeff Johnsone7245742012-09-05 17:12:55 -070010746allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010747 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010748 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070010749
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010750 /* Acquire wakelock to handle the case where APP's tries to suspend
10751 * immediatly after the driver gets connect request(i.e after scan)
10752 * from supplicant, this result in app's is suspending and not able
10753 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010754 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010755
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010756#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010757 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010758#endif
10759
Jeff Johnson295189b2012-06-20 16:38:30 -070010760 EXIT();
10761 return 0;
10762}
10763
10764/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053010765 * FUNCTION: hdd_isConnectionInProgress
10766 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010767 *
10768 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010769v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010770{
10771 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10772 hdd_station_ctx_t *pHddStaCtx = NULL;
10773 hdd_adapter_t *pAdapter = NULL;
10774 VOS_STATUS status = 0;
10775 v_U8_t staId = 0;
10776 v_U8_t *staMac = NULL;
10777
c_hpothu9b781ba2013-12-30 20:57:45 +053010778 if (TRUE == pHddCtx->btCoexModeSet)
10779 {
10780 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053010781 FL("BTCoex Mode operation in progress"));
10782 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053010783 }
10784
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010785 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10786
10787 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10788 {
10789 pAdapter = pAdapterNode->pAdapter;
10790
10791 if( pAdapter )
10792 {
10793 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010794 "%s: Adapter with device mode %s (%d) exists",
10795 __func__, hdd_device_modetoString(pAdapter->device_mode),
10796 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010797 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053010798 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10799 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
10800 (eConnectionState_Connecting ==
10801 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
10802 {
10803 hddLog(VOS_TRACE_LEVEL_ERROR,
10804 "%s: %p(%d) Connection is in progress", __func__,
10805 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10806 return VOS_TRUE;
10807 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010808 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053010809 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010810 {
10811 hddLog(VOS_TRACE_LEVEL_ERROR,
10812 "%s: %p(%d) Reassociation is in progress", __func__,
10813 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10814 return VOS_TRUE;
10815 }
10816 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010817 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10818 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010819 {
10820 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10821 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010822 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010823 {
10824 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
10825 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010826 "%s: client " MAC_ADDRESS_STR
10827 " is in the middle of WPS/EAPOL exchange.", __func__,
10828 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010829 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010830 }
10831 }
10832 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
10833 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
10834 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010835 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10836 ptSapContext pSapCtx = NULL;
10837 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10838 if(pSapCtx == NULL){
10839 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10840 FL("psapCtx is NULL"));
10841 return VOS_FALSE;
10842 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010843 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
10844 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010845 if ((pSapCtx->aStaInfo[staId].isUsed) &&
10846 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010847 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010848 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010849
10850 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010851 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
10852 "middle of WPS/EAPOL exchange.", __func__,
10853 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010854 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010855 }
10856 }
10857 }
10858 }
10859 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10860 pAdapterNode = pNext;
10861 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053010862 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010863}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010864
10865/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010866 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070010867 * this scan respond to scan trigger and update cfg80211 scan database
10868 * later, scan dump command can be used to recieve scan results
10869 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010870int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010871#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10872 struct net_device *dev,
10873#endif
10874 struct cfg80211_scan_request *request)
10875{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010876 hdd_adapter_t *pAdapter = NULL;
10877 hdd_context_t *pHddCtx = NULL;
10878 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010879 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010880 tCsrScanRequest scanRequest;
10881 tANI_U8 *channelList = NULL, i;
10882 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010883 int status;
10884 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010885 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010886 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053010887 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010888 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053010889 v_S7_t rssi=0;
10890 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010891
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010892#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
10893 struct net_device *dev = NULL;
10894 if (NULL == request)
10895 {
10896 hddLog(VOS_TRACE_LEVEL_ERROR,
10897 "%s: scan req param null", __func__);
10898 return -EINVAL;
10899 }
10900 dev = request->wdev->netdev;
10901#endif
10902
10903 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
10904 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
10905 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10906
Jeff Johnson295189b2012-06-20 16:38:30 -070010907 ENTER();
10908
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010909 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10910 __func__, hdd_device_modetoString(pAdapter->device_mode),
10911 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010912
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010913 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010914 if (0 != status)
10915 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010916 return status;
10917 }
10918
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010919 if (NULL == pwextBuf)
10920 {
10921 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
10922 __func__);
10923 return -EIO;
10924 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010925 cfg_param = pHddCtx->cfg_ini;
10926 pScanInfo = &pHddCtx->scan_info;
10927
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053010928 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10929 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
10930 {
10931 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
10932 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
10933 }
10934
Jeff Johnson295189b2012-06-20 16:38:30 -070010935#ifdef WLAN_BTAMP_FEATURE
10936 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010937 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070010938 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010939 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010940 "%s: No scanning when AMP is on", __func__);
10941 return -EOPNOTSUPP;
10942 }
10943#endif
10944 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010945 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010946 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010947 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010948 "%s: Not scanning on device_mode = %s (%d)",
10949 __func__, hdd_device_modetoString(pAdapter->device_mode),
10950 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010951 return -EOPNOTSUPP;
10952 }
10953
10954 if (TRUE == pScanInfo->mScanPending)
10955 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010956 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
10957 {
10958 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
10959 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010960 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010961 }
10962
Hanumantha Reddy Pothula4b6be062015-08-18 14:06:24 +053010963 // Don't allow scan if PNO scan is going on.
10964 if (pHddCtx->isPnoEnable)
10965 {
10966 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
10967 FL("pno scan in progress"));
10968 return -EBUSY;
10969 }
10970
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010971 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070010972 //Channel and action frame is pending
10973 //Otherwise Cancel Remain On Channel and allow Scan
10974 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010975 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070010976 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010977 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010978 return -EBUSY;
10979 }
10980
Jeff Johnson295189b2012-06-20 16:38:30 -070010981 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
10982 {
10983 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080010984 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010985 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010986 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010987 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
10988 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010989 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010990 "%s: MAX TM Level Scan not allowed", __func__);
10991 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010992 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010993 }
10994 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
10995
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010996 /* Check if scan is allowed at this point of time.
10997 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010998 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010999 {
11000 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
11001 return -EBUSY;
11002 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011003
Jeff Johnson295189b2012-06-20 16:38:30 -070011004 vos_mem_zero( &scanRequest, sizeof(scanRequest));
11005
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011006 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
11007 * Becasue of this, driver is assuming that this is not wildcard scan and so
11008 * is not aging out the scan results.
11009 */
11010 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070011011 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011012 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070011013 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011014
11015 if ((request->ssids) && (0 < request->n_ssids))
11016 {
11017 tCsrSSIDInfo *SsidInfo;
11018 int j;
11019 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
11020 /* Allocate num_ssid tCsrSSIDInfo structure */
11021 SsidInfo = scanRequest.SSIDs.SSIDList =
11022 ( tCsrSSIDInfo *)vos_mem_malloc(
11023 request->n_ssids*sizeof(tCsrSSIDInfo));
11024
11025 if(NULL == scanRequest.SSIDs.SSIDList)
11026 {
11027 hddLog(VOS_TRACE_LEVEL_ERROR,
11028 "%s: memory alloc failed SSIDInfo buffer", __func__);
11029 return -ENOMEM;
11030 }
11031
11032 /* copy all the ssid's and their length */
11033 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
11034 {
11035 /* get the ssid length */
11036 SsidInfo->SSID.length = request->ssids[j].ssid_len;
11037 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
11038 SsidInfo->SSID.length);
11039 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
11040 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
11041 j, SsidInfo->SSID.ssId);
11042 }
11043 /* set the scan type to active */
11044 scanRequest.scanType = eSIR_ACTIVE_SCAN;
11045 }
11046 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070011047 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053011048 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
11049 TRACE_CODE_HDD_CFG80211_SCAN,
11050 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070011051 /* set the scan type to active */
11052 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070011053 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011054 else
11055 {
11056 /*Set the scan type to default type, in this case it is ACTIVE*/
11057 scanRequest.scanType = pScanInfo->scan_mode;
11058 }
11059 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
11060 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070011061
11062 /* set BSSType to default type */
11063 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
11064
11065 /*TODO: scan the requested channels only*/
11066
11067 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011068 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070011069 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011070 hddLog(VOS_TRACE_LEVEL_WARN,
11071 "No of Scan Channels exceeded limit: %d", request->n_channels);
11072 request->n_channels = MAX_CHANNEL;
11073 }
11074
11075 hddLog(VOS_TRACE_LEVEL_INFO,
11076 "No of Scan Channels: %d", request->n_channels);
11077
11078
11079 if( request->n_channels )
11080 {
11081 char chList [(request->n_channels*5)+1];
11082 int len;
11083 channelList = vos_mem_malloc( request->n_channels );
11084 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053011085 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011086 hddLog(VOS_TRACE_LEVEL_ERROR,
11087 "%s: memory alloc failed channelList", __func__);
11088 status = -ENOMEM;
11089 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053011090 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011091
11092 for( i = 0, len = 0; i < request->n_channels ; i++ )
11093 {
11094 channelList[i] = request->channels[i]->hw_value;
11095 len += snprintf(chList+len, 5, "%d ", channelList[i]);
11096 }
11097
Nirav Shah20ac06f2013-12-12 18:14:06 +053011098 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011099 "Channel-List: %s ", chList);
11100 }
c_hpothu53512302014-04-15 18:49:53 +053011101
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011102 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
11103 scanRequest.ChannelInfo.ChannelList = channelList;
11104
11105 /* set requestType to full scan */
11106 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
11107
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011108 /* if there is back to back scan happening in driver with in
11109 * nDeferScanTimeInterval interval driver should defer new scan request
11110 * and should provide last cached scan results instead of new channel list.
11111 * This rule is not applicable if scan is p2p scan.
11112 * This condition will work only in case when last request no of channels
11113 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053011114 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053011115 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011116 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011117
Sushant Kaushik86592172015-04-27 16:35:03 +053011118 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
11119 /* if wps ie is NULL , then only defer scan */
11120 if ( pWpsIe == NULL &&
11121 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053011122 {
11123 if ( pScanInfo->last_scan_timestamp !=0 &&
11124 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
11125 {
11126 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
11127 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
11128 vos_mem_compare(pScanInfo->last_scan_channelList,
11129 channelList, pScanInfo->last_scan_numChannels))
11130 {
11131 hddLog(VOS_TRACE_LEVEL_WARN,
11132 " New and old station scan time differ is less then %u",
11133 pHddCtx->cfg_ini->nDeferScanTimeInterval);
11134
11135 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011136 pAdapter);
11137
Agarwal Ashish57e84372014-12-05 18:26:53 +053011138 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053011139 "Return old cached scan as all channels and no of channels are same");
11140
Agarwal Ashish57e84372014-12-05 18:26:53 +053011141 if (0 > ret)
11142 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011143
Agarwal Ashish57e84372014-12-05 18:26:53 +053011144 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053011145
11146 status = eHAL_STATUS_SUCCESS;
11147 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053011148 }
11149 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053011150 }
11151
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011152 /* Flush the scan results(only p2p beacons) for STA scan and P2P
11153 * search (Flush on both full scan and social scan but not on single
11154 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
11155 */
11156
11157 /* Supplicant does single channel scan after 8-way handshake
11158 * and in that case driver shoudnt flush scan results. If
11159 * driver flushes the scan results here and unfortunately if
11160 * the AP doesnt respond to our probe req then association
11161 * fails which is not desired
11162 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011163 if ((request->n_ssids == 1)
11164 && (request->ssids != NULL)
11165 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
11166 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011167
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011168 if( is_p2p_scan ||
11169 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011170 {
11171 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
11172 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
11173 pAdapter->sessionId );
11174 }
11175
11176 if( request->ie_len )
11177 {
11178 /* save this for future association (join requires this) */
11179 /*TODO: Array needs to be converted to dynamic allocation,
11180 * as multiple ie.s can be sent in cfg80211_scan_request structure
11181 * CR 597966
11182 */
11183 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
11184 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
11185 pScanInfo->scanAddIE.length = request->ie_len;
11186
11187 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11188 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11189 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011190 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011191 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070011192 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011193 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
11194 memcpy( pwextBuf->roamProfile.addIEScan,
11195 request->ie, request->ie_len);
11196 }
11197 else
11198 {
11199 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
11200 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011201 }
11202
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011203 }
11204 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
11205 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
11206
11207 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
11208 request->ie_len);
11209 if (pP2pIe != NULL)
11210 {
11211#ifdef WLAN_FEATURE_P2P_DEBUG
11212 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
11213 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
11214 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053011215 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011216 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
11217 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11218 "Go nego completed to Connection is started");
11219 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11220 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053011221 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011222 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
11223 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011224 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011225 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
11226 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11227 "Disconnected state to Connection is started");
11228 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11229 "for 4way Handshake");
11230 }
11231#endif
11232
11233 /* no_cck will be set during p2p find to disable 11b rates */
11234 if(TRUE == request->no_cck)
11235 {
11236 hddLog(VOS_TRACE_LEVEL_INFO,
11237 "%s: This is a P2P Search", __func__);
11238 scanRequest.p2pSearch = 1;
11239
11240 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053011241 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011242 /* set requestType to P2P Discovery */
11243 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
11244 }
11245
11246 /*
11247 Skip Dfs Channel in case of P2P Search
11248 if it is set in ini file
11249 */
11250 if(cfg_param->skipDfsChnlInP2pSearch)
11251 {
11252 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011253 }
11254 else
11255 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011256 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011257 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011258
Agarwal Ashish4f616132013-12-30 23:32:50 +053011259 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011260 }
11261 }
11262
11263 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
11264
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011265#ifdef FEATURE_WLAN_TDLS
11266 /* if tdls disagree scan right now, return immediately.
11267 tdls will schedule the scan when scan is allowed. (return SUCCESS)
11268 or will reject the scan if any TDLS is in progress. (return -EBUSY)
11269 */
11270 status = wlan_hdd_tdls_scan_callback (pAdapter,
11271 wiphy,
11272#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11273 dev,
11274#endif
11275 request);
11276 if(status <= 0)
11277 {
11278 if(!status)
11279 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
11280 "scan rejected %d", __func__, status);
11281 else
11282 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
11283 __func__, status);
11284
11285 return status;
11286 }
11287#endif
11288
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011289 /* acquire the wakelock to avoid the apps suspend during the scan. To
11290 * address the following issues.
11291 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
11292 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
11293 * for long time, this result in apps running at full power for long time.
11294 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
11295 * be stuck in full power because of resume BMPS
11296 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011297 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011298
Nirav Shah20ac06f2013-12-12 18:14:06 +053011299 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11300 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011301 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
11302 scanRequest.requestType, scanRequest.scanType,
11303 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053011304 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
11305
Siddharth Bhal76972212014-10-15 16:22:51 +053011306 if (pHddCtx->spoofMacAddr.isEnabled)
11307 {
11308 hddLog(VOS_TRACE_LEVEL_INFO,
11309 "%s: MAC Spoofing enabled for current scan", __func__);
11310 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
11311 * to fill TxBds for probe request during current scan
11312 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011313 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053011314 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011315
11316 if(status != VOS_STATUS_SUCCESS)
11317 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011318 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011319 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053011320#ifdef FEATURE_WLAN_TDLS
11321 wlan_hdd_tdls_scan_done_callback(pAdapter);
11322#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011323 goto free_mem;
11324 }
Siddharth Bhal76972212014-10-15 16:22:51 +053011325 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053011326 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070011327 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011328 pAdapter->sessionId, &scanRequest, &scanId,
11329 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070011330
Jeff Johnson295189b2012-06-20 16:38:30 -070011331 if (eHAL_STATUS_SUCCESS != status)
11332 {
11333 hddLog(VOS_TRACE_LEVEL_ERROR,
11334 "%s: sme_ScanRequest returned error %d", __func__, status);
11335 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011336 if(eHAL_STATUS_RESOURCES == status)
11337 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011338 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
11339 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011340 status = -EBUSY;
11341 } else {
11342 status = -EIO;
11343 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011344 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011345
11346#ifdef FEATURE_WLAN_TDLS
11347 wlan_hdd_tdls_scan_done_callback(pAdapter);
11348#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011349 goto free_mem;
11350 }
11351
11352 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011353 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011354 pAdapter->request = request;
11355 pScanInfo->scanId = scanId;
11356
11357 complete(&pScanInfo->scan_req_completion_event);
11358
11359free_mem:
11360 if( scanRequest.SSIDs.SSIDList )
11361 {
11362 vos_mem_free(scanRequest.SSIDs.SSIDList);
11363 }
11364
11365 if( channelList )
11366 vos_mem_free( channelList );
11367
11368 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011369 return status;
11370}
11371
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011372int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
11373#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11374 struct net_device *dev,
11375#endif
11376 struct cfg80211_scan_request *request)
11377{
11378 int ret;
11379
11380 vos_ssr_protect(__func__);
11381 ret = __wlan_hdd_cfg80211_scan(wiphy,
11382#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11383 dev,
11384#endif
11385 request);
11386 vos_ssr_unprotect(__func__);
11387
11388 return ret;
11389}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011390
11391void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
11392{
11393 v_U8_t iniDot11Mode =
11394 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
11395 eHddDot11Mode hddDot11Mode = iniDot11Mode;
11396
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011397 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
11398 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011399 switch ( iniDot11Mode )
11400 {
11401 case eHDD_DOT11_MODE_AUTO:
11402 case eHDD_DOT11_MODE_11ac:
11403 case eHDD_DOT11_MODE_11ac_ONLY:
11404#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053011405 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
11406 sme_IsFeatureSupportedByFW(DOT11AC) )
11407 hddDot11Mode = eHDD_DOT11_MODE_11ac;
11408 else
11409 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011410#else
11411 hddDot11Mode = eHDD_DOT11_MODE_11n;
11412#endif
11413 break;
11414 case eHDD_DOT11_MODE_11n:
11415 case eHDD_DOT11_MODE_11n_ONLY:
11416 hddDot11Mode = eHDD_DOT11_MODE_11n;
11417 break;
11418 default:
11419 hddDot11Mode = iniDot11Mode;
11420 break;
11421 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011422#ifdef WLAN_FEATURE_AP_HT40_24G
11423 if (operationChannel > SIR_11B_CHANNEL_END)
11424#endif
11425 {
11426 /* This call decides required channel bonding mode */
11427 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011428 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
11429 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011430 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011431}
11432
Jeff Johnson295189b2012-06-20 16:38:30 -070011433/*
11434 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011435 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011436 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011437int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011438 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070011439{
11440 int status = 0;
11441 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080011442 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011443 v_U32_t roamId;
11444 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070011445 eCsrAuthType RSNAuthType;
11446
11447 ENTER();
11448
11449 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080011450 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11451
11452 status = wlan_hdd_validate_context(pHddCtx);
11453 if (status)
11454 {
Yue Mae36e3552014-03-05 17:06:20 -080011455 return status;
11456 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011457
Jeff Johnson295189b2012-06-20 16:38:30 -070011458 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
11459 {
11460 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
11461 return -EINVAL;
11462 }
11463
11464 pRoamProfile = &pWextState->roamProfile;
11465
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011466 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070011467 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011468 hdd_station_ctx_t *pHddStaCtx;
11469 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011470
Siddharth Bhalda0d1622015-04-24 15:47:49 +053011471 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
11472
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011473 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070011474 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
11475 {
11476 /*QoS not enabled in cfg file*/
11477 pRoamProfile->uapsd_mask = 0;
11478 }
11479 else
11480 {
11481 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011482 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070011483 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
11484 }
11485
11486 pRoamProfile->SSIDs.numOfSSIDs = 1;
11487 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
11488 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011489 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070011490 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
11491 ssid, ssid_len);
11492
11493 if (bssid)
11494 {
11495 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
11496 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
11497 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011498 /* Save BSSID in seperate variable as well, as RoamProfile
11499 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070011500 case of join failure we should send valid BSSID to supplicant
11501 */
11502 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
11503 WNI_CFG_BSSID_LEN);
11504 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070011505 else
11506 {
11507 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
11508 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011509
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011510 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
11511 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011512 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
11513 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011514 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011515 /*set gen ie*/
11516 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
11517 /*set auth*/
11518 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
11519 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011520#ifdef FEATURE_WLAN_WAPI
11521 if (pAdapter->wapi_info.nWapiMode)
11522 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011523 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011524 switch (pAdapter->wapi_info.wapiAuthMode)
11525 {
11526 case WAPI_AUTH_MODE_PSK:
11527 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011528 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011529 pAdapter->wapi_info.wapiAuthMode);
11530 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
11531 break;
11532 }
11533 case WAPI_AUTH_MODE_CERT:
11534 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011535 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011536 pAdapter->wapi_info.wapiAuthMode);
11537 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
11538 break;
11539 }
11540 } // End of switch
11541 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
11542 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
11543 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011544 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011545 pRoamProfile->AuthType.numEntries = 1;
11546 pRoamProfile->EncryptionType.numEntries = 1;
11547 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11548 pRoamProfile->mcEncryptionType.numEntries = 1;
11549 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11550 }
11551 }
11552#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011553#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011554 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011555 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11556 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
11557 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011558 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
11559 sizeof (tSirGtkOffloadParams));
11560 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011561 }
11562#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011563 pRoamProfile->csrPersona = pAdapter->device_mode;
11564
Jeff Johnson32d95a32012-09-10 13:15:23 -070011565 if( operatingChannel )
11566 {
11567 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
11568 pRoamProfile->ChannelInfo.numOfChannels = 1;
11569 }
Chet Lanctot186b5732013-03-18 10:26:30 -070011570 else
11571 {
11572 pRoamProfile->ChannelInfo.ChannelList = NULL;
11573 pRoamProfile->ChannelInfo.numOfChannels = 0;
11574 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011575 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
11576 {
11577 hdd_select_cbmode(pAdapter,operatingChannel);
11578 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011579
Agarwal Ashish40f9b872015-09-01 16:17:35 +053011580 /*
11581 * Change conn_state to connecting before sme_RoamConnect(),
11582 * because sme_RoamConnect() has a direct path to call
11583 * hdd_smeRoamCallback(), which will change the conn_state
11584 * If direct path, conn_state will be accordingly changed
11585 * to NotConnected or Associated by either
11586 * hdd_AssociationCompletionHandler() or hdd_DisConnectHandler()
11587 * in sme_RoamCallback()
11588 * if sme_RomConnect is to be queued,
11589 * Connecting state will remain until it is completed.
11590 * If connection state is not changed,
11591 * connection state will remain in eConnectionState_NotConnected state.
11592 * In hdd_AssociationCompletionHandler, "hddDisconInProgress" is set to true
11593 * if conn state is eConnectionState_NotConnected.
11594 * If "hddDisconInProgress" is set to true then cfg80211 layer is not
11595 * informed of connect result indication which is an issue.
11596 */
11597
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011598 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11599 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053011600 {
11601 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish40f9b872015-09-01 16:17:35 +053011602 FL("Set HDD connState to eConnectionState_Connecting"));
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011603 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
11604 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053011605 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011606 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011607 pAdapter->sessionId, pRoamProfile, &roamId);
11608
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011609 if ((eHAL_STATUS_SUCCESS != status) &&
11610 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11611 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011612
11613 {
Agarwal Ashish40f9b872015-09-01 16:17:35 +053011614 hddLog(VOS_TRACE_LEVEL_ERROR,
11615 FL("sme_RoamConnect (session %d) failed with status %d. -> NotConnected"),
11616 pAdapter->sessionId, status);
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011617 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011618 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011619 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011620 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011621
11622 pRoamProfile->ChannelInfo.ChannelList = NULL;
11623 pRoamProfile->ChannelInfo.numOfChannels = 0;
11624
Jeff Johnson295189b2012-06-20 16:38:30 -070011625 }
11626 else
11627 {
11628 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
11629 return -EINVAL;
11630 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011631 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011632 return status;
11633}
11634
11635/*
11636 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
11637 * This function is used to set the authentication type (OPEN/SHARED).
11638 *
11639 */
11640static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
11641 enum nl80211_auth_type auth_type)
11642{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011643 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011644 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11645
11646 ENTER();
11647
11648 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011649 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070011650 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011651 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011652 hddLog(VOS_TRACE_LEVEL_INFO,
11653 "%s: set authentication type to AUTOSWITCH", __func__);
11654 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
11655 break;
11656
11657 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011658#ifdef WLAN_FEATURE_VOWIFI_11R
11659 case NL80211_AUTHTYPE_FT:
11660#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011661 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011662 "%s: set authentication type to OPEN", __func__);
11663 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
11664 break;
11665
11666 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011667 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011668 "%s: set authentication type to SHARED", __func__);
11669 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
11670 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011671#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011672 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011673 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011674 "%s: set authentication type to CCKM WPA", __func__);
11675 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
11676 break;
11677#endif
11678
11679
11680 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011681 hddLog(VOS_TRACE_LEVEL_ERROR,
11682 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011683 auth_type);
11684 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
11685 return -EINVAL;
11686 }
11687
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011688 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011689 pHddStaCtx->conn_info.authType;
11690 return 0;
11691}
11692
11693/*
11694 * FUNCTION: wlan_hdd_set_akm_suite
11695 * This function is used to set the key mgmt type(PSK/8021x).
11696 *
11697 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011698static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011699 u32 key_mgmt
11700 )
11701{
11702 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11703 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053011704 /* Should be in ieee802_11_defs.h */
11705#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
11706#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070011707 /*set key mgmt type*/
11708 switch(key_mgmt)
11709 {
11710 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053011711 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011712#ifdef WLAN_FEATURE_VOWIFI_11R
11713 case WLAN_AKM_SUITE_FT_PSK:
11714#endif
11715 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070011716 __func__);
11717 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
11718 break;
11719
11720 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053011721 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011722#ifdef WLAN_FEATURE_VOWIFI_11R
11723 case WLAN_AKM_SUITE_FT_8021X:
11724#endif
11725 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070011726 __func__);
11727 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11728 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011729#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011730#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
11731#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
11732 case WLAN_AKM_SUITE_CCKM:
11733 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
11734 __func__);
11735 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
11736 break;
11737#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070011738#ifndef WLAN_AKM_SUITE_OSEN
11739#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
11740 case WLAN_AKM_SUITE_OSEN:
11741 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
11742 __func__);
11743 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11744 break;
11745#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011746
11747 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011748 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011749 __func__, key_mgmt);
11750 return -EINVAL;
11751
11752 }
11753 return 0;
11754}
11755
11756/*
11757 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011758 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070011759 * (NONE/WEP40/WEP104/TKIP/CCMP).
11760 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011761static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
11762 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070011763 bool ucast
11764 )
11765{
11766 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011767 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011768 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11769
11770 ENTER();
11771
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011772 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011773 {
Ratheesh S P36dbc932015-08-07 14:28:57 +053011774 hddLog(VOS_TRACE_LEVEL_INFO, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070011775 __func__, cipher);
11776 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11777 }
11778 else
11779 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011780
Jeff Johnson295189b2012-06-20 16:38:30 -070011781 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011782 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011783 {
11784 case IW_AUTH_CIPHER_NONE:
11785 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11786 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011787
Jeff Johnson295189b2012-06-20 16:38:30 -070011788 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011789 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070011790 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011791
Jeff Johnson295189b2012-06-20 16:38:30 -070011792 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011793 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070011794 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011795
Jeff Johnson295189b2012-06-20 16:38:30 -070011796 case WLAN_CIPHER_SUITE_TKIP:
11797 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
11798 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011799
Jeff Johnson295189b2012-06-20 16:38:30 -070011800 case WLAN_CIPHER_SUITE_CCMP:
11801 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11802 break;
11803#ifdef FEATURE_WLAN_WAPI
11804 case WLAN_CIPHER_SUITE_SMS4:
11805 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
11806 break;
11807#endif
11808
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011809#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011810 case WLAN_CIPHER_SUITE_KRK:
11811 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
11812 break;
11813#endif
11814 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011815 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011816 __func__, cipher);
11817 return -EOPNOTSUPP;
11818 }
11819 }
11820
11821 if (ucast)
11822 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011823 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011824 __func__, encryptionType);
11825 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11826 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011827 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011828 encryptionType;
11829 }
11830 else
11831 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011832 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011833 __func__, encryptionType);
11834 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
11835 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
11836 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
11837 }
11838
11839 return 0;
11840}
11841
11842
11843/*
11844 * FUNCTION: wlan_hdd_cfg80211_set_ie
11845 * This function is used to parse WPA/RSN IE's.
11846 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011847int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011848#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11849 const u8 *ie,
11850#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011851 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011852#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011853 size_t ie_len
11854 )
11855{
11856 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011857#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11858 const u8 *genie = ie;
11859#else
Jeff Johnson295189b2012-06-20 16:38:30 -070011860 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011861#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011862 v_U16_t remLen = ie_len;
11863#ifdef FEATURE_WLAN_WAPI
11864 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
11865 u16 *tmp;
11866 v_U16_t akmsuiteCount;
11867 int *akmlist;
11868#endif
11869 ENTER();
11870
11871 /* clear previous assocAddIE */
11872 pWextState->assocAddIE.length = 0;
11873 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011874 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011875
11876 while (remLen >= 2)
11877 {
11878 v_U16_t eLen = 0;
11879 v_U8_t elementId;
11880 elementId = *genie++;
11881 eLen = *genie++;
11882 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011883
Arif Hussain6d2a3322013-11-17 19:50:10 -080011884 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070011885 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011886
11887 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070011888 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011889 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011890 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 -070011891 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011892 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011893 "%s: Invalid WPA IE", __func__);
11894 return -EINVAL;
11895 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011896 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070011897 {
11898 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011899 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011900 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011901
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011902 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011903 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011904 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
11905 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011906 VOS_ASSERT(0);
11907 return -ENOMEM;
11908 }
11909 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11910 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11911 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011912
Jeff Johnson295189b2012-06-20 16:38:30 -070011913 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
11914 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11915 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11916 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011917 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
11918 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011919 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
11920 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11921 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
11922 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
11923 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
11924 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011925 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053011926 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011927 {
11928 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011929 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011930 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011931
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011932 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011933 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011934 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11935 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011936 VOS_ASSERT(0);
11937 return -ENOMEM;
11938 }
11939 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11940 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11941 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011942
Jeff Johnson295189b2012-06-20 16:38:30 -070011943 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11944 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11945 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011946#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011947 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
11948 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011949 /*Consider WFD IE, only for P2P Client */
11950 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11951 {
11952 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011953 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011954 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011955
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011956 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011957 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011958 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11959 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011960 VOS_ASSERT(0);
11961 return -ENOMEM;
11962 }
11963 // WFD IE is saved to Additional IE ; it should be accumulated to handle
11964 // WPS IE + P2P IE + WFD IE
11965 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11966 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011967
Jeff Johnson295189b2012-06-20 16:38:30 -070011968 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11969 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11970 }
11971#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011972 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011973 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011974 HS20_OUI_TYPE_SIZE)) )
11975 {
11976 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011977 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011978 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011979
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011980 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011981 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011982 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11983 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011984 VOS_ASSERT(0);
11985 return -ENOMEM;
11986 }
11987 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11988 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011989
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011990 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11991 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11992 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011993 /* Appending OSEN Information Element in Assiciation Request */
11994 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
11995 OSEN_OUI_TYPE_SIZE)) )
11996 {
11997 v_U16_t curAddIELen = pWextState->assocAddIE.length;
11998 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
11999 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012000
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012001 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070012002 {
12003 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12004 "Need bigger buffer space");
12005 VOS_ASSERT(0);
12006 return -ENOMEM;
12007 }
12008 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12009 pWextState->assocAddIE.length += eLen + 2;
12010
12011 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
12012 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12013 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12014 }
12015
Abhishek Singh4322e622015-06-10 15:42:54 +053012016 /* Update only for WPA IE */
12017 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
12018 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070012019
12020 /* populating as ADDIE in beacon frames */
12021 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012022 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070012023 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
12024 {
12025 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
12026 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
12027 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
12028 {
12029 hddLog(LOGE,
12030 "Coldn't pass "
12031 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
12032 }
12033 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
12034 else
12035 hddLog(LOGE,
12036 "Could not pass on "
12037 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
12038
12039 /* IBSS mode doesn't contain params->proberesp_ies still
12040 beaconIE's need to be populated in probe response frames */
12041 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
12042 {
12043 u16 rem_probe_resp_ie_len = eLen + 2;
12044 u8 probe_rsp_ie_len[3] = {0};
12045 u8 counter = 0;
12046
12047 /* Check Probe Resp Length if it is greater then 255 then
12048 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
12049 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
12050 not able Store More then 255 bytes into One Variable */
12051
12052 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
12053 {
12054 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
12055 {
12056 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
12057 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
12058 }
12059 else
12060 {
12061 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
12062 rem_probe_resp_ie_len = 0;
12063 }
12064 }
12065
12066 rem_probe_resp_ie_len = 0;
12067
12068 if (probe_rsp_ie_len[0] > 0)
12069 {
12070 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12071 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
12072 (tANI_U8*)(genie - 2),
12073 probe_rsp_ie_len[0], NULL,
12074 eANI_BOOLEAN_FALSE)
12075 == eHAL_STATUS_FAILURE)
12076 {
12077 hddLog(LOGE,
12078 "Could not pass"
12079 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
12080 }
12081 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
12082 }
12083
12084 if (probe_rsp_ie_len[1] > 0)
12085 {
12086 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12087 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
12088 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
12089 probe_rsp_ie_len[1], NULL,
12090 eANI_BOOLEAN_FALSE)
12091 == eHAL_STATUS_FAILURE)
12092 {
12093 hddLog(LOGE,
12094 "Could not pass"
12095 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
12096 }
12097 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
12098 }
12099
12100 if (probe_rsp_ie_len[2] > 0)
12101 {
12102 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
12103 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
12104 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
12105 probe_rsp_ie_len[2], NULL,
12106 eANI_BOOLEAN_FALSE)
12107 == eHAL_STATUS_FAILURE)
12108 {
12109 hddLog(LOGE,
12110 "Could not pass"
12111 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
12112 }
12113 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
12114 }
12115
12116 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
12117 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
12118 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
12119 {
12120 hddLog(LOGE,
12121 "Could not pass"
12122 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
12123 }
12124 }
12125 else
12126 {
12127 // Reset WNI_CFG_PROBE_RSP Flags
12128 wlan_hdd_reset_prob_rspies(pAdapter);
12129
12130 hddLog(VOS_TRACE_LEVEL_INFO,
12131 "%s: No Probe Response IE received in set beacon",
12132 __func__);
12133 }
12134 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070012135 break;
12136 case DOT11F_EID_RSN:
12137 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
12138 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
12139 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
12140 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
12141 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
12142 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053012143
12144 /* Appending Extended Capabilities with Interworking bit set
12145 * in Assoc Req.
12146 *
12147 * In assoc req this EXT Cap will only be taken into account if
12148 * interworkingService bit is set to 1. Currently
12149 * driver is only interested in interworkingService capability
12150 * from supplicant. If in future any other EXT Cap info is
12151 * required from supplicat, it needs to be handled while
12152 * sending Assoc Req in LIM.
12153 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012154 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012155 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012156 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012157 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012158 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012159
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053012160 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012161 {
Jeff Johnson902c9832012-12-10 14:28:09 -080012162 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
12163 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012164 VOS_ASSERT(0);
12165 return -ENOMEM;
12166 }
12167 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
12168 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012169
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012170 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
12171 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
12172 break;
12173 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012174#ifdef FEATURE_WLAN_WAPI
12175 case WLAN_EID_WAPI:
12176 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012177 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012178 pAdapter->wapi_info.nWapiMode);
12179 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012180 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070012181 akmsuiteCount = WPA_GET_LE16(tmp);
12182 tmp = tmp + 1;
12183 akmlist = (int *)(tmp);
12184 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
12185 {
12186 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
12187 }
12188 else
12189 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012190 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070012191 VOS_ASSERT(0);
12192 return -EINVAL;
12193 }
12194
12195 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
12196 {
12197 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012198 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012199 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012200 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012201 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012202 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012203 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012204 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012205 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
12206 }
12207 break;
12208#endif
12209 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012210 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012211 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012212 /* when Unknown IE is received we should break and continue
12213 * to the next IE in the buffer instead we were returning
12214 * so changing this to break */
12215 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070012216 }
12217 genie += eLen;
12218 remLen -= eLen;
12219 }
12220 EXIT();
12221 return 0;
12222}
12223
12224/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012225 * FUNCTION: hdd_isWPAIEPresent
12226 * Parse the received IE to find the WPA IE
12227 *
12228 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012229static bool hdd_isWPAIEPresent(
12230#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
12231 const u8 *ie,
12232#else
12233 u8 *ie,
12234#endif
12235 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012236{
12237 v_U8_t eLen = 0;
12238 v_U16_t remLen = ie_len;
12239 v_U8_t elementId = 0;
12240
12241 while (remLen >= 2)
12242 {
12243 elementId = *ie++;
12244 eLen = *ie++;
12245 remLen -= 2;
12246 if (eLen > remLen)
12247 {
12248 hddLog(VOS_TRACE_LEVEL_ERROR,
12249 "%s: IE length is wrong %d", __func__, eLen);
12250 return FALSE;
12251 }
12252 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
12253 {
12254 /* OUI - 0x00 0X50 0XF2
12255 WPA Information Element - 0x01
12256 WPA version - 0x01*/
12257 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
12258 return TRUE;
12259 }
12260 ie += eLen;
12261 remLen -= eLen;
12262 }
12263 return FALSE;
12264}
12265
12266/*
Jeff Johnson295189b2012-06-20 16:38:30 -070012267 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012268 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012269 * parameters during connect operation.
12270 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012271int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012272 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012273 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012274{
12275 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012276 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012277 ENTER();
12278
12279 /*set wpa version*/
12280 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
12281
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012282 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012283 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053012284 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012285 {
12286 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12287 }
12288 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
12289 {
12290 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12291 }
12292 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012293
12294 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012295 pWextState->wpaVersion);
12296
12297 /*set authentication type*/
12298 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
12299
12300 if (0 > status)
12301 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012302 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012303 "%s: failed to set authentication type ", __func__);
12304 return status;
12305 }
12306
12307 /*set key mgmt type*/
12308 if (req->crypto.n_akm_suites)
12309 {
12310 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
12311 if (0 > status)
12312 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012313 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070012314 __func__);
12315 return status;
12316 }
12317 }
12318
12319 /*set pairwise cipher type*/
12320 if (req->crypto.n_ciphers_pairwise)
12321 {
12322 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
12323 req->crypto.ciphers_pairwise[0], true);
12324 if (0 > status)
12325 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012326 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012327 "%s: failed to set unicast cipher type", __func__);
12328 return status;
12329 }
12330 }
12331 else
12332 {
12333 /*Reset previous cipher suite to none*/
12334 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
12335 if (0 > status)
12336 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012337 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012338 "%s: failed to set unicast cipher type", __func__);
12339 return status;
12340 }
12341 }
12342
12343 /*set group cipher type*/
12344 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
12345 false);
12346
12347 if (0 > status)
12348 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012349 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070012350 __func__);
12351 return status;
12352 }
12353
Chet Lanctot186b5732013-03-18 10:26:30 -070012354#ifdef WLAN_FEATURE_11W
12355 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
12356#endif
12357
Jeff Johnson295189b2012-06-20 16:38:30 -070012358 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
12359 if (req->ie_len)
12360 {
12361 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
12362 if ( 0 > status)
12363 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012364 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012365 __func__);
12366 return status;
12367 }
12368 }
12369
12370 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012371 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012372 {
12373 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
12374 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
12375 )
12376 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012377 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070012378 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
12379 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012380 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012381 __func__);
12382 return -EOPNOTSUPP;
12383 }
12384 else
12385 {
12386 u8 key_len = req->key_len;
12387 u8 key_idx = req->key_idx;
12388
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012389 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012390 && (CSR_MAX_NUM_KEY > key_idx)
12391 )
12392 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012393 hddLog(VOS_TRACE_LEVEL_INFO,
12394 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012395 __func__, key_idx, key_len);
12396 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012397 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012398 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012399 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012400 (u8)key_len;
12401 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
12402 }
12403 }
12404 }
12405 }
12406
12407 return status;
12408}
12409
12410/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012411 * FUNCTION: wlan_hdd_try_disconnect
12412 * This function is used to disconnect from previous
12413 * connection
12414 */
12415static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
12416{
12417 long ret = 0;
12418 hdd_station_ctx_t *pHddStaCtx;
12419 eMib_dot11DesiredBssType connectedBssType;
12420
12421 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12422
12423 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
12424
12425 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
12426 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
12427 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
12428 {
12429 /* Issue disconnect to CSR */
12430 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12431 if( eHAL_STATUS_SUCCESS ==
12432 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12433 pAdapter->sessionId,
12434 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12435 {
12436 ret = wait_for_completion_interruptible_timeout(
12437 &pAdapter->disconnect_comp_var,
12438 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12439 if (0 >= ret)
12440 {
12441 hddLog(LOGE, FL("Failed to receive disconnect event"));
12442 return -EALREADY;
12443 }
12444 }
12445 }
12446 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
12447 {
12448 ret = wait_for_completion_interruptible_timeout(
12449 &pAdapter->disconnect_comp_var,
12450 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12451 if (0 >= ret)
12452 {
12453 hddLog(LOGE, FL("Failed to receive disconnect event"));
12454 return -EALREADY;
12455 }
12456 }
12457
12458 return 0;
12459}
12460
12461/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053012462 * FUNCTION: __wlan_hdd_cfg80211_connect
12463 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070012464 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012465static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012466 struct net_device *ndev,
12467 struct cfg80211_connect_params *req
12468 )
12469{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012470 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012471 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012472 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053012473 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012474
12475 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012476
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012477 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12478 TRACE_CODE_HDD_CFG80211_CONNECT,
12479 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012480 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012481 "%s: device_mode = %s (%d)", __func__,
12482 hdd_device_modetoString(pAdapter->device_mode),
12483 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012484
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012485 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012486 if (!pHddCtx)
12487 {
12488 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12489 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053012490 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012491 }
12492
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012493 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012494 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012495 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012496 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012497 }
12498
Agarwal Ashish51325b52014-06-16 16:50:49 +053012499 if (vos_max_concurrent_connections_reached()) {
12500 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12501 return -ECONNREFUSED;
12502 }
12503
Jeff Johnson295189b2012-06-20 16:38:30 -070012504#ifdef WLAN_BTAMP_FEATURE
12505 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012506 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070012507 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012508 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012509 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012510 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070012511 }
12512#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012513
12514 //If Device Mode is Station Concurrent Sessions Exit BMps
12515 //P2P Mode will be taken care in Open/close adapter
12516 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012517 (vos_concurrent_open_sessions_running())) {
12518 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
12519 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012520 }
12521
12522 /*Try disconnecting if already in connected state*/
12523 status = wlan_hdd_try_disconnect(pAdapter);
12524 if ( 0 > status)
12525 {
12526 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12527 " connection"));
12528 return -EALREADY;
12529 }
12530
Jeff Johnson295189b2012-06-20 16:38:30 -070012531 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012532 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070012533
12534 if ( 0 > status)
12535 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012536 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070012537 __func__);
12538 return status;
12539 }
Mohit Khanna765234a2012-09-11 15:08:35 -070012540 if ( req->channel )
12541 {
12542 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
12543 req->ssid_len, req->bssid,
12544 req->channel->hw_value);
12545 }
12546 else
12547 {
12548 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012549 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070012550 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012551
Sushant Kaushikd7083982015-03-18 14:33:24 +053012552 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012553 {
12554 //ReEnable BMPS if disabled
12555 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
12556 (NULL != pHddCtx))
12557 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012558 if (pHddCtx->hdd_wlan_suspended)
12559 {
12560 hdd_set_pwrparams(pHddCtx);
12561 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012562 //ReEnable Bmps and Imps back
12563 hdd_enable_bmps_imps(pHddCtx);
12564 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053012565 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070012566 return status;
12567 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012568 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012569 EXIT();
12570 return status;
12571}
12572
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012573static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
12574 struct net_device *ndev,
12575 struct cfg80211_connect_params *req)
12576{
12577 int ret;
12578 vos_ssr_protect(__func__);
12579 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
12580 vos_ssr_unprotect(__func__);
12581
12582 return ret;
12583}
Jeff Johnson295189b2012-06-20 16:38:30 -070012584
12585/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012586 * FUNCTION: wlan_hdd_disconnect
12587 * This function is used to issue a disconnect request to SME
12588 */
12589int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
12590{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012591 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012592 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012593 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012594 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012595
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012596 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012597
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012598 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012599 if (0 != status)
12600 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012601 return status;
12602 }
12603
Sushant Kaushikb4834d22015-07-15 15:29:05 +053012604 if (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)
12605 {
12606 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
12607 pAdapter->sessionId);
12608 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012609 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012610
Agarwal Ashish47d18112014-08-04 19:55:07 +053012611 /* Need to apply spin lock before decreasing active sessions
12612 * as there can be chance for double decrement if context switch
12613 * Calls hdd_DisConnectHandler.
12614 */
12615
12616 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012617 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
12618 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012619 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
12620 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053012621 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
12622 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012623
Abhishek Singhf4669da2014-05-26 15:07:49 +053012624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053012625 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
12626
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012627 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012628
Mihir Shete182a0b22014-08-18 16:08:48 +053012629 /*
12630 * stop tx queues before deleting STA/BSS context from the firmware.
12631 * tx has to be disabled because the firmware can get busy dropping
12632 * the tx frames after BSS/STA has been deleted and will not send
12633 * back a response resulting in WDI timeout
12634 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053012635 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053012636 netif_tx_disable(pAdapter->dev);
12637 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012638
Mihir Shete182a0b22014-08-18 16:08:48 +053012639 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012640 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12641 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012642 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
12643 {
12644 hddLog(VOS_TRACE_LEVEL_INFO,
12645 FL("status = %d, already disconnected"),
12646 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012647
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012648 }
12649 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012650 {
12651 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012652 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012653 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012654 result = -EINVAL;
12655 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012656 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012657 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012658 &pAdapter->disconnect_comp_var,
12659 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012660 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012661 {
12662 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012663 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012664 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012665 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012666 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012667 {
12668 hddLog(VOS_TRACE_LEVEL_ERROR,
12669 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012670 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012671 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012672disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012673 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12674 FL("Set HDD connState to eConnectionState_NotConnected"));
12675 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
12676
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012677 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012678 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012679}
12680
12681
12682/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012683 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070012684 * This function is used to issue a disconnect request to SME
12685 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012686static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012687 struct net_device *dev,
12688 u16 reason
12689 )
12690{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012691 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012692 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012693 tCsrRoamProfile *pRoamProfile;
12694 hdd_station_ctx_t *pHddStaCtx;
12695 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012696#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012697 tANI_U8 staIdx;
12698#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012699
Jeff Johnson295189b2012-06-20 16:38:30 -070012700 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012701
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012702 if (!pAdapter) {
12703 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
12704 return -EINVAL;
12705 }
12706
12707 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12708 if (!pHddStaCtx) {
12709 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
12710 return -EINVAL;
12711 }
12712
12713 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12714 status = wlan_hdd_validate_context(pHddCtx);
12715 if (0 != status)
12716 {
12717 return status;
12718 }
12719
12720 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
12721
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012722 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12723 TRACE_CODE_HDD_CFG80211_DISCONNECT,
12724 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012725 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
12726 __func__, hdd_device_modetoString(pAdapter->device_mode),
12727 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012728
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012729 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
12730 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070012731
Jeff Johnson295189b2012-06-20 16:38:30 -070012732 if (NULL != pRoamProfile)
12733 {
12734 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012735 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
12736 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070012737 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012738 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070012739 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012740 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012741 switch(reason)
12742 {
12743 case WLAN_REASON_MIC_FAILURE:
12744 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
12745 break;
12746
12747 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
12748 case WLAN_REASON_DISASSOC_AP_BUSY:
12749 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
12750 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
12751 break;
12752
12753 case WLAN_REASON_PREV_AUTH_NOT_VALID:
12754 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053012755 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070012756 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
12757 break;
12758
Jeff Johnson295189b2012-06-20 16:38:30 -070012759 default:
12760 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
12761 break;
12762 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012763 pScanInfo = &pHddCtx->scan_info;
12764 if (pScanInfo->mScanPending)
12765 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012766 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012767 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012768 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012769 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012770 }
Agarwal Ashishc089cec2015-08-10 13:10:04 +053012771 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012772#ifdef FEATURE_WLAN_TDLS
12773 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012774 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012775 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012776 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
12777 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012778 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012779 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012780 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012781 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012782 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012783 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012784 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012785 status = sme_DeleteTdlsPeerSta(
12786 WLAN_HDD_GET_HAL_CTX(pAdapter),
12787 pAdapter->sessionId,
12788 mac);
12789 if (status != eHAL_STATUS_SUCCESS) {
12790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
12791 return -EPERM;
12792 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012793 }
12794 }
12795#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012796 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012797 status = wlan_hdd_disconnect(pAdapter, reasonCode);
12798 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070012799 {
12800 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012801 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012802 __func__, (int)status );
12803 return -EINVAL;
12804 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012805 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012806 else
12807 {
12808 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
12809 "called while in %d state", __func__,
12810 pHddStaCtx->conn_info.connState);
12811 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012812 }
12813 else
12814 {
12815 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
12816 }
12817
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012818 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012819 return status;
12820}
12821
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012822static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
12823 struct net_device *dev,
12824 u16 reason
12825 )
12826{
12827 int ret;
12828 vos_ssr_protect(__func__);
12829 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
12830 vos_ssr_unprotect(__func__);
12831
12832 return ret;
12833}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012834
Jeff Johnson295189b2012-06-20 16:38:30 -070012835/*
12836 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012837 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012838 * settings in IBSS mode.
12839 */
12840static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012841 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012842 struct cfg80211_ibss_params *params
12843 )
12844{
12845 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012846 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012847 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12848 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012849
Jeff Johnson295189b2012-06-20 16:38:30 -070012850 ENTER();
12851
12852 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070012853 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070012854
12855 if (params->ie_len && ( NULL != params->ie) )
12856 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012857 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12858 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012859 {
12860 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12861 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12862 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012863 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012864 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012865 tDot11fIEWPA dot11WPAIE;
12866 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012867 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012868
Wilson Yang00256342013-10-10 23:13:38 -070012869 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012870 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12871 params->ie_len, DOT11F_EID_WPA);
12872 if ( NULL != ie )
12873 {
12874 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12875 // Unpack the WPA IE
12876 //Skip past the EID byte and length byte - and four byte WiFi OUI
12877 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
12878 &ie[2+4],
12879 ie[1] - 4,
12880 &dot11WPAIE);
12881 /*Extract the multicast cipher, the encType for unicast
12882 cipher for wpa-none is none*/
12883 encryptionType =
12884 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
12885 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012886 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012887
Jeff Johnson295189b2012-06-20 16:38:30 -070012888 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
12889
12890 if (0 > status)
12891 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012892 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012893 __func__);
12894 return status;
12895 }
12896 }
12897
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012898 pWextState->roamProfile.AuthType.authType[0] =
12899 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012900 eCSR_AUTH_TYPE_OPEN_SYSTEM;
12901
12902 if (params->privacy)
12903 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012904 /* Security enabled IBSS, At this time there is no information available
12905 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070012906 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012907 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070012908 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012909 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070012910 *enable privacy bit in beacons */
12911
12912 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12913 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012914 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
12915 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070012916 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12917 pWextState->roamProfile.EncryptionType.numEntries = 1;
12918 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070012919 return status;
12920}
12921
12922/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012923 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012924 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012925 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012926static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012927 struct net_device *dev,
12928 struct cfg80211_ibss_params *params
12929 )
12930{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012931 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012932 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12933 tCsrRoamProfile *pRoamProfile;
12934 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012935 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12936 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012937 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070012938
12939 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012940
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012941 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12942 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
12943 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012944 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012945 "%s: device_mode = %s (%d)", __func__,
12946 hdd_device_modetoString(pAdapter->device_mode),
12947 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012948
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012949 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012950 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012951 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012952 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012953 }
12954
12955 if (NULL == pWextState)
12956 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012957 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012958 __func__);
12959 return -EIO;
12960 }
12961
Agarwal Ashish51325b52014-06-16 16:50:49 +053012962 if (vos_max_concurrent_connections_reached()) {
12963 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12964 return -ECONNREFUSED;
12965 }
12966
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012967 /*Try disconnecting if already in connected state*/
12968 status = wlan_hdd_try_disconnect(pAdapter);
12969 if ( 0 > status)
12970 {
12971 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12972 " IBSS connection"));
12973 return -EALREADY;
12974 }
12975
Jeff Johnson295189b2012-06-20 16:38:30 -070012976 pRoamProfile = &pWextState->roamProfile;
12977
12978 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
12979 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012980 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012981 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012982 return -EINVAL;
12983 }
12984
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012985 /* BSSID is provided by upper layers hence no need to AUTO generate */
12986 if (NULL != params->bssid) {
12987 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12988 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
12989 hddLog (VOS_TRACE_LEVEL_ERROR,
12990 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12991 return -EIO;
12992 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012993 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012994 }
krunal sonie9002db2013-11-25 14:24:17 -080012995 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
12996 {
12997 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12998 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
12999 {
13000 hddLog (VOS_TRACE_LEVEL_ERROR,
13001 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
13002 return -EIO;
13003 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013004
13005 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080013006 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013007 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080013008 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070013009
Jeff Johnson295189b2012-06-20 16:38:30 -070013010 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070013011 if (NULL !=
13012#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
13013 params->chandef.chan)
13014#else
13015 params->channel)
13016#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013017 {
13018 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013019 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
13020 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
13021 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
13022 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013023
13024 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013025 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070013026 ieee80211_frequency_to_channel(
13027#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
13028 params->chandef.chan->center_freq);
13029#else
13030 params->channel->center_freq);
13031#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013032
13033 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
13034 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070013035 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013036 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
13037 __func__);
13038 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070013039 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013040
13041 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013042 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013043 if (channelNum == validChan[indx])
13044 {
13045 break;
13046 }
13047 }
13048 if (indx >= numChans)
13049 {
13050 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070013051 __func__, channelNum);
13052 return -EINVAL;
13053 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013054 /* Set the Operational Channel */
13055 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
13056 channelNum);
13057 pRoamProfile->ChannelInfo.numOfChannels = 1;
13058 pHddStaCtx->conn_info.operationChannel = channelNum;
13059 pRoamProfile->ChannelInfo.ChannelList =
13060 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070013061 }
13062
13063 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013064 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070013065 if (status < 0)
13066 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013067 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070013068 __func__);
13069 return status;
13070 }
13071
13072 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013073 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070013074 params->ssid_len, params->bssid,
13075 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070013076
13077 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070013078 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013079
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013080 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013081 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013082}
13083
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013084static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
13085 struct net_device *dev,
13086 struct cfg80211_ibss_params *params
13087 )
13088{
13089 int ret = 0;
13090
13091 vos_ssr_protect(__func__);
13092 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
13093 vos_ssr_unprotect(__func__);
13094
13095 return ret;
13096}
13097
Jeff Johnson295189b2012-06-20 16:38:30 -070013098/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013099 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013100 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070013101 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013102static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013103 struct net_device *dev
13104 )
13105{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013106 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013107 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
13108 tCsrRoamProfile *pRoamProfile;
13109 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013110 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013111
13112 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053013113
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013114 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13115 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
13116 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013117 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013118 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013119 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013120 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013121 }
13122
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053013123 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
13124 hdd_device_modetoString(pAdapter->device_mode),
13125 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070013126 if (NULL == pWextState)
13127 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013128 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070013129 __func__);
13130 return -EIO;
13131 }
13132
13133 pRoamProfile = &pWextState->roamProfile;
13134
13135 /* Issue disconnect only if interface type is set to IBSS */
13136 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
13137 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013138 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070013139 __func__);
13140 return -EINVAL;
13141 }
13142
13143 /* Issue Disconnect request */
13144 INIT_COMPLETION(pAdapter->disconnect_comp_var);
13145 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
13146 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
13147
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013148 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013149 return 0;
13150}
13151
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013152static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
13153 struct net_device *dev
13154 )
13155{
13156 int ret = 0;
13157
13158 vos_ssr_protect(__func__);
13159 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
13160 vos_ssr_unprotect(__func__);
13161
13162 return ret;
13163}
13164
Jeff Johnson295189b2012-06-20 16:38:30 -070013165/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013166 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070013167 * This function is used to set the phy parameters
13168 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
13169 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013170static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070013171 u32 changed)
13172{
13173 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
13174 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013175 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013176
13177 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013178
13179 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013180 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
13181 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013182
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013183 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013184 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013185 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013186 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013187 }
13188
Jeff Johnson295189b2012-06-20 16:38:30 -070013189 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
13190 {
13191 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
13192 WNI_CFG_RTS_THRESHOLD_STAMAX :
13193 wiphy->rts_threshold;
13194
13195 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013196 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070013197 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013198 hddLog(VOS_TRACE_LEVEL_ERROR,
13199 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013200 __func__, rts_threshold);
13201 return -EINVAL;
13202 }
13203
13204 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
13205 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013206 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013207 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013208 hddLog(VOS_TRACE_LEVEL_ERROR,
13209 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013210 __func__, rts_threshold);
13211 return -EIO;
13212 }
13213
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013214 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013215 rts_threshold);
13216 }
13217
13218 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
13219 {
13220 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
13221 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
13222 wiphy->frag_threshold;
13223
13224 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013225 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013226 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013227 hddLog(VOS_TRACE_LEVEL_ERROR,
13228 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013229 frag_threshold);
13230 return -EINVAL;
13231 }
13232
13233 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
13234 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013235 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013236 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013237 hddLog(VOS_TRACE_LEVEL_ERROR,
13238 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013239 __func__, frag_threshold);
13240 return -EIO;
13241 }
13242
13243 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
13244 frag_threshold);
13245 }
13246
13247 if ((changed & WIPHY_PARAM_RETRY_SHORT)
13248 || (changed & WIPHY_PARAM_RETRY_LONG))
13249 {
13250 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
13251 wiphy->retry_short :
13252 wiphy->retry_long;
13253
13254 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
13255 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
13256 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013257 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013258 __func__, retry_value);
13259 return -EINVAL;
13260 }
13261
13262 if (changed & WIPHY_PARAM_RETRY_SHORT)
13263 {
13264 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
13265 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013266 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013267 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013268 hddLog(VOS_TRACE_LEVEL_ERROR,
13269 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013270 __func__, retry_value);
13271 return -EIO;
13272 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013273 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013274 __func__, retry_value);
13275 }
13276 else if (changed & WIPHY_PARAM_RETRY_SHORT)
13277 {
13278 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
13279 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013280 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013281 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013282 hddLog(VOS_TRACE_LEVEL_ERROR,
13283 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013284 __func__, retry_value);
13285 return -EIO;
13286 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013287 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013288 __func__, retry_value);
13289 }
13290 }
13291
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013292 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013293 return 0;
13294}
13295
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013296static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
13297 u32 changed)
13298{
13299 int ret;
13300
13301 vos_ssr_protect(__func__);
13302 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
13303 vos_ssr_unprotect(__func__);
13304
13305 return ret;
13306}
13307
Jeff Johnson295189b2012-06-20 16:38:30 -070013308/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013309 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013310 * This function is used to set the txpower
13311 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013312static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013313#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13314 struct wireless_dev *wdev,
13315#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013316#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013317 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013318#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013319 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013320#endif
13321 int dbm)
13322{
13323 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013324 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013325 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13326 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013327 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013328
13329 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013330
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013331 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13332 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
13333 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013334 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013335 if (0 != status)
13336 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013337 return status;
13338 }
13339
13340 hHal = pHddCtx->hHal;
13341
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013342 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
13343 dbm, ccmCfgSetCallback,
13344 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013345 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013346 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013347 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
13348 return -EIO;
13349 }
13350
13351 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
13352 dbm);
13353
13354 switch(type)
13355 {
13356 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
13357 /* Fall through */
13358 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
13359 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
13360 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013361 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
13362 __func__);
13363 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013364 }
13365 break;
13366 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013367 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070013368 __func__);
13369 return -EOPNOTSUPP;
13370 break;
13371 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013372 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
13373 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070013374 return -EIO;
13375 }
13376
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013377 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013378 return 0;
13379}
13380
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013381static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
13382#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13383 struct wireless_dev *wdev,
13384#endif
13385#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13386 enum tx_power_setting type,
13387#else
13388 enum nl80211_tx_power_setting type,
13389#endif
13390 int dbm)
13391{
13392 int ret;
13393 vos_ssr_protect(__func__);
13394 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
13395#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13396 wdev,
13397#endif
13398#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13399 type,
13400#else
13401 type,
13402#endif
13403 dbm);
13404 vos_ssr_unprotect(__func__);
13405
13406 return ret;
13407}
13408
Jeff Johnson295189b2012-06-20 16:38:30 -070013409/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013410 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013411 * This function is used to read the txpower
13412 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013413static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013414#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13415 struct wireless_dev *wdev,
13416#endif
13417 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070013418{
13419
13420 hdd_adapter_t *pAdapter;
13421 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013422 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013423
Jeff Johnsone7245742012-09-05 17:12:55 -070013424 ENTER();
13425
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013426 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013427 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013428 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013429 *dbm = 0;
13430 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013431 }
13432
Jeff Johnson295189b2012-06-20 16:38:30 -070013433 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
13434 if (NULL == pAdapter)
13435 {
13436 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
13437 return -ENOENT;
13438 }
13439
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053013440 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13441 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
13442 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070013443 wlan_hdd_get_classAstats(pAdapter);
13444 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
13445
Jeff Johnsone7245742012-09-05 17:12:55 -070013446 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013447 return 0;
13448}
13449
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013450static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
13451#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13452 struct wireless_dev *wdev,
13453#endif
13454 int *dbm)
13455{
13456 int ret;
13457
13458 vos_ssr_protect(__func__);
13459 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
13460#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13461 wdev,
13462#endif
13463 dbm);
13464 vos_ssr_unprotect(__func__);
13465
13466 return ret;
13467}
13468
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013469static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013470#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13471 const u8* mac,
13472#else
13473 u8* mac,
13474#endif
13475 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070013476{
13477 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13478 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13479 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053013480 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070013481
13482 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
13483 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070013484
13485 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
13486 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
13487 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
13488 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
13489 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
13490 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
13491 tANI_U16 maxRate = 0;
13492 tANI_U16 myRate;
13493 tANI_U16 currentRate = 0;
13494 tANI_U8 maxSpeedMCS = 0;
13495 tANI_U8 maxMCSIdx = 0;
13496 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053013497 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013498 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013499 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013500
Leo Chang6f8870f2013-03-26 18:11:36 -070013501#ifdef WLAN_FEATURE_11AC
13502 tANI_U32 vht_mcs_map;
13503 eDataRate11ACMaxMcs vhtMaxMcs;
13504#endif /* WLAN_FEATURE_11AC */
13505
Jeff Johnsone7245742012-09-05 17:12:55 -070013506 ENTER();
13507
Jeff Johnson295189b2012-06-20 16:38:30 -070013508 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
13509 (0 == ssidlen))
13510 {
13511 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
13512 " Invalid ssidlen, %d", __func__, ssidlen);
13513 /*To keep GUI happy*/
13514 return 0;
13515 }
13516
Mukul Sharma811205f2014-07-09 21:07:30 +053013517 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
13518 {
13519 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13520 "%s: Roaming in progress, so unable to proceed this request", __func__);
13521 return 0;
13522 }
13523
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013524 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013525 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013526 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013527 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013528 }
13529
Hanumantha Reddy Pothuladce66742015-08-25 18:08:44 +053013530 wlan_hdd_get_station_stats(pAdapter);
13531 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070013532
Kiet Lam3b17fc82013-09-27 05:24:08 +053013533 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
13534 sinfo->filled |= STATION_INFO_SIGNAL;
13535
c_hpothu09f19542014-05-30 21:53:31 +053013536 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053013537 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
13538 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053013539 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053013540 {
13541 rate_flags = pAdapter->maxRateFlags;
13542 }
c_hpothu44ff4e02014-05-08 00:13:57 +053013543
Jeff Johnson295189b2012-06-20 16:38:30 -070013544 //convert to the UI units of 100kbps
13545 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
13546
13547#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070013548 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 -070013549 sinfo->signal,
13550 pCfg->reportMaxLinkSpeed,
13551 myRate,
13552 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013553 (int) pCfg->linkSpeedRssiMid,
13554 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070013555 (int) rate_flags,
13556 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013557#endif //LINKSPEED_DEBUG_ENABLED
13558
13559 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
13560 {
13561 // we do not want to necessarily report the current speed
13562 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
13563 {
13564 // report the max possible speed
13565 rssidx = 0;
13566 }
13567 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
13568 {
13569 // report the max possible speed with RSSI scaling
13570 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
13571 {
13572 // report the max possible speed
13573 rssidx = 0;
13574 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013575 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070013576 {
13577 // report middle speed
13578 rssidx = 1;
13579 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013580 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
13581 {
13582 // report middle speed
13583 rssidx = 2;
13584 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013585 else
13586 {
13587 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013588 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070013589 }
13590 }
13591 else
13592 {
13593 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
13594 hddLog(VOS_TRACE_LEVEL_ERROR,
13595 "%s: Invalid value for reportMaxLinkSpeed: %u",
13596 __func__, pCfg->reportMaxLinkSpeed);
13597 rssidx = 0;
13598 }
13599
13600 maxRate = 0;
13601
13602 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013603 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
13604 OperationalRates, &ORLeng))
13605 {
13606 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13607 /*To keep GUI happy*/
13608 return 0;
13609 }
13610
Jeff Johnson295189b2012-06-20 16:38:30 -070013611 for (i = 0; i < ORLeng; i++)
13612 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013613 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013614 {
13615 /* Validate Rate Set */
13616 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
13617 {
13618 currentRate = supported_data_rate[j].supported_rate[rssidx];
13619 break;
13620 }
13621 }
13622 /* Update MAX rate */
13623 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13624 }
13625
13626 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013627 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
13628 ExtendedRates, &ERLeng))
13629 {
13630 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13631 /*To keep GUI happy*/
13632 return 0;
13633 }
13634
Jeff Johnson295189b2012-06-20 16:38:30 -070013635 for (i = 0; i < ERLeng; i++)
13636 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013637 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013638 {
13639 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
13640 {
13641 currentRate = supported_data_rate[j].supported_rate[rssidx];
13642 break;
13643 }
13644 }
13645 /* Update MAX rate */
13646 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13647 }
c_hpothu79aab322014-07-14 21:11:01 +053013648
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013649 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053013650 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013651 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053013652 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070013653 {
c_hpothu79aab322014-07-14 21:11:01 +053013654 if (rate_flags & eHAL_TX_RATE_VHT80)
13655 mode = 2;
13656 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
13657 mode = 1;
13658 else
13659 mode = 0;
13660
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013661 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
13662 MCSRates, &MCSLeng))
13663 {
13664 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13665 /*To keep GUI happy*/
13666 return 0;
13667 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013668 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070013669#ifdef WLAN_FEATURE_11AC
13670 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013671 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070013672 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013673 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013674 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070013675 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070013676 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013677 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013678 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013679 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070013680 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013681 maxMCSIdx = 7;
13682 }
13683 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
13684 {
13685 maxMCSIdx = 8;
13686 }
13687 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
13688 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013689 //VHT20 is supporting 0~8
13690 if (rate_flags & eHAL_TX_RATE_VHT20)
13691 maxMCSIdx = 8;
13692 else
13693 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070013694 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013695
c_hpothu79aab322014-07-14 21:11:01 +053013696 if (0 != rssidx)/*check for scaled */
13697 {
13698 //get middle rate MCS index if rssi=1/2
13699 for (i=0; i <= maxMCSIdx; i++)
13700 {
13701 if (sinfo->signal <= rssiMcsTbl[mode][i])
13702 {
13703 maxMCSIdx = i;
13704 break;
13705 }
13706 }
13707 }
13708
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013709 if (rate_flags & eHAL_TX_RATE_VHT80)
13710 {
13711 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
13712 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
13713 }
13714 else if (rate_flags & eHAL_TX_RATE_VHT40)
13715 {
13716 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
13717 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
13718 }
13719 else if (rate_flags & eHAL_TX_RATE_VHT20)
13720 {
13721 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
13722 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
13723 }
13724
Leo Chang6f8870f2013-03-26 18:11:36 -070013725 maxSpeedMCS = 1;
13726 if (currentRate > maxRate)
13727 {
13728 maxRate = currentRate;
13729 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013730
Leo Chang6f8870f2013-03-26 18:11:36 -070013731 }
13732 else
13733#endif /* WLAN_FEATURE_11AC */
13734 {
13735 if (rate_flags & eHAL_TX_RATE_HT40)
13736 {
13737 rateFlag |= 1;
13738 }
13739 if (rate_flags & eHAL_TX_RATE_SGI)
13740 {
13741 rateFlag |= 2;
13742 }
13743
Girish Gowli01abcee2014-07-31 20:18:55 +053013744 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053013745 if (rssidx == 1 || rssidx == 2)
13746 {
13747 //get middle rate MCS index if rssi=1/2
13748 for (i=0; i <= 7; i++)
13749 {
13750 if (sinfo->signal <= rssiMcsTbl[mode][i])
13751 {
13752 temp = i+1;
13753 break;
13754 }
13755 }
13756 }
c_hpothu79aab322014-07-14 21:11:01 +053013757
13758 for (i = 0; i < MCSLeng; i++)
13759 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013760 for (j = 0; j < temp; j++)
13761 {
13762 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
13763 {
13764 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053013765 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013766 break;
13767 }
13768 }
13769 if ((j < temp) && (currentRate > maxRate))
13770 {
13771 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070013772 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013773 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053013774 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013775 }
13776 }
13777
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013778 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
13779 {
13780 maxRate = myRate;
13781 maxSpeedMCS = 1;
13782 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13783 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013784 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053013785 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070013786 {
13787 maxRate = myRate;
13788 if (rate_flags & eHAL_TX_RATE_LEGACY)
13789 {
13790 maxSpeedMCS = 0;
13791 }
13792 else
13793 {
13794 maxSpeedMCS = 1;
13795 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13796 }
13797 }
13798
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013799 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070013800 {
13801 sinfo->txrate.legacy = maxRate;
13802#ifdef LINKSPEED_DEBUG_ENABLED
13803 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
13804#endif //LINKSPEED_DEBUG_ENABLED
13805 }
13806 else
13807 {
13808 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070013809#ifdef WLAN_FEATURE_11AC
13810 sinfo->txrate.nss = 1;
13811 if (rate_flags & eHAL_TX_RATE_VHT80)
13812 {
13813 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013814 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070013815 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013816 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070013817 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013818 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13819 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13820 }
13821 else if (rate_flags & eHAL_TX_RATE_VHT20)
13822 {
13823 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13824 }
13825#endif /* WLAN_FEATURE_11AC */
13826 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
13827 {
13828 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13829 if (rate_flags & eHAL_TX_RATE_HT40)
13830 {
13831 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13832 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013833 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013834 if (rate_flags & eHAL_TX_RATE_SGI)
13835 {
13836 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13837 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013838
Jeff Johnson295189b2012-06-20 16:38:30 -070013839#ifdef LINKSPEED_DEBUG_ENABLED
13840 pr_info("Reporting MCS rate %d flags %x\n",
13841 sinfo->txrate.mcs,
13842 sinfo->txrate.flags );
13843#endif //LINKSPEED_DEBUG_ENABLED
13844 }
13845 }
13846 else
13847 {
13848 // report current rate instead of max rate
13849
13850 if (rate_flags & eHAL_TX_RATE_LEGACY)
13851 {
13852 //provide to the UI in units of 100kbps
13853 sinfo->txrate.legacy = myRate;
13854#ifdef LINKSPEED_DEBUG_ENABLED
13855 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
13856#endif //LINKSPEED_DEBUG_ENABLED
13857 }
13858 else
13859 {
13860 //must be MCS
13861 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013862#ifdef WLAN_FEATURE_11AC
13863 sinfo->txrate.nss = 1;
13864 if (rate_flags & eHAL_TX_RATE_VHT80)
13865 {
13866 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13867 }
13868 else
13869#endif /* WLAN_FEATURE_11AC */
13870 {
13871 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13872 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013873 if (rate_flags & eHAL_TX_RATE_SGI)
13874 {
13875 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13876 }
13877 if (rate_flags & eHAL_TX_RATE_HT40)
13878 {
13879 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13880 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013881#ifdef WLAN_FEATURE_11AC
13882 else if (rate_flags & eHAL_TX_RATE_VHT80)
13883 {
13884 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
13885 }
13886#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070013887#ifdef LINKSPEED_DEBUG_ENABLED
13888 pr_info("Reporting actual MCS rate %d flags %x\n",
13889 sinfo->txrate.mcs,
13890 sinfo->txrate.flags );
13891#endif //LINKSPEED_DEBUG_ENABLED
13892 }
13893 }
13894 sinfo->filled |= STATION_INFO_TX_BITRATE;
13895
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013896 sinfo->tx_packets =
13897 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
13898 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
13899 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
13900 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
13901
13902 sinfo->tx_retries =
13903 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
13904 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
13905 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
13906 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
13907
13908 sinfo->tx_failed =
13909 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
13910 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
13911 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
13912 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
13913
13914 sinfo->filled |=
13915 STATION_INFO_TX_PACKETS |
13916 STATION_INFO_TX_RETRIES |
13917 STATION_INFO_TX_FAILED;
13918
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013919 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13920 TRACE_CODE_HDD_CFG80211_GET_STA,
13921 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013922 EXIT();
13923 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013924}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013925#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13926static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
13927 const u8* mac, struct station_info *sinfo)
13928#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013929static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
13930 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013931#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013932{
13933 int ret;
13934
13935 vos_ssr_protect(__func__);
13936 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
13937 vos_ssr_unprotect(__func__);
13938
13939 return ret;
13940}
13941
13942static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070013943 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070013944{
13945 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013946 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013947 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013948 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013949
Jeff Johnsone7245742012-09-05 17:12:55 -070013950 ENTER();
13951
Jeff Johnson295189b2012-06-20 16:38:30 -070013952 if (NULL == pAdapter)
13953 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013954 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013955 return -ENODEV;
13956 }
13957
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013958 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13959 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
13960 pAdapter->sessionId, timeout));
13961
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013962 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013963 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013964 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013965 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013966 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013967 }
13968
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013969 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
13970 (TRUE == pHddCtx->hdd_wlan_suspended) &&
13971 (pHddCtx->cfg_ini->fhostArpOffload) &&
13972 (eConnectionState_Associated ==
13973 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13974 {
Amar Singhald53568e2013-09-26 11:03:45 -070013975
13976 hddLog(VOS_TRACE_LEVEL_INFO,
13977 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053013978 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013979 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13980 {
13981 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013982 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013983 __func__, vos_status);
13984 }
13985 }
13986
Jeff Johnson295189b2012-06-20 16:38:30 -070013987 /**The get power cmd from the supplicant gets updated by the nl only
13988 *on successful execution of the function call
13989 *we are oppositely mapped w.r.t mode in the driver
13990 **/
13991 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
13992
13993 if (VOS_STATUS_E_FAILURE == vos_status)
13994 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013995 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13996 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013997 return -EINVAL;
13998 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013999 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070014000 return 0;
14001}
14002
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014003static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
14004 struct net_device *dev, bool mode, int timeout)
14005{
14006 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014007
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014008 vos_ssr_protect(__func__);
14009 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
14010 vos_ssr_unprotect(__func__);
14011
14012 return ret;
14013}
Jeff Johnson295189b2012-06-20 16:38:30 -070014014#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014015static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
14016 struct net_device *netdev,
14017 u8 key_index)
14018{
14019 ENTER();
14020 return 0;
14021}
14022
Jeff Johnson295189b2012-06-20 16:38:30 -070014023static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014024 struct net_device *netdev,
14025 u8 key_index)
14026{
14027 int ret;
14028 vos_ssr_protect(__func__);
14029 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
14030 vos_ssr_unprotect(__func__);
14031 return ret;
14032}
14033#endif //LINUX_VERSION_CODE
14034
14035#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
14036static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
14037 struct net_device *dev,
14038 struct ieee80211_txq_params *params)
14039{
14040 ENTER();
14041 return 0;
14042}
14043#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14044static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
14045 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070014046{
Jeff Johnsone7245742012-09-05 17:12:55 -070014047 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070014048 return 0;
14049}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014050#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070014051
14052#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
14053static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014054 struct net_device *dev,
14055 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070014056{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014057 int ret;
14058
14059 vos_ssr_protect(__func__);
14060 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
14061 vos_ssr_unprotect(__func__);
14062 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014063}
14064#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
14065static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
14066 struct ieee80211_txq_params *params)
14067{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014068 int ret;
14069
14070 vos_ssr_protect(__func__);
14071 ret = __wlan_hdd_set_txq_params(wiphy, params);
14072 vos_ssr_unprotect(__func__);
14073 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070014074}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014075#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070014076
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014077static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014078 struct net_device *dev,
14079 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070014080{
14081 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014082 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014083 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014084 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014085 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014086 v_CONTEXT_t pVosContext = NULL;
14087 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014088
Jeff Johnsone7245742012-09-05 17:12:55 -070014089 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014090
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014091 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070014092 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014093 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070014094 return -EINVAL;
14095 }
14096
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014097 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14098 TRACE_CODE_HDD_CFG80211_DEL_STA,
14099 pAdapter->sessionId, pAdapter->device_mode));
14100
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014101 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14102 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014103 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014104 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014105 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014106 }
14107
Jeff Johnson295189b2012-06-20 16:38:30 -070014108 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014109 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070014110 )
14111 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014112 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
14113 pSapCtx = VOS_GET_SAP_CB(pVosContext);
14114 if(pSapCtx == NULL){
14115 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14116 FL("psapCtx is NULL"));
14117 return -ENOENT;
14118 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014119 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070014120 {
14121 v_U16_t i;
14122 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
14123 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014124 if ((pSapCtx->aStaInfo[i].isUsed) &&
14125 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070014126 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014127 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014128 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014129 ETHER_ADDR_LEN);
14130
Jeff Johnson295189b2012-06-20 16:38:30 -070014131 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014132 "%s: Delete STA with MAC::"
14133 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014134 __func__,
14135 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
14136 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070014137 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014138 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070014139 }
14140 }
14141 }
14142 else
14143 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014144
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014145 vos_status = hdd_softap_GetStaId(pAdapter,
14146 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014147 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14148 {
14149 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014150 "%s: Skip this DEL STA as this is not used::"
14151 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014152 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014153 return -ENOENT;
14154 }
14155
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014156 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014157 {
14158 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080014159 "%s: Skip this DEL STA as deauth is in progress::"
14160 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014161 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014162 return -ENOENT;
14163 }
14164
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014165 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014166
Jeff Johnson295189b2012-06-20 16:38:30 -070014167 hddLog(VOS_TRACE_LEVEL_INFO,
14168 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080014169 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070014170 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014171 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014172
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014173 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014174 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14175 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014176 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014177 hddLog(VOS_TRACE_LEVEL_INFO,
14178 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080014179 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014180 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014181 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014182 return -ENOENT;
14183 }
14184
Jeff Johnson295189b2012-06-20 16:38:30 -070014185 }
14186 }
14187
14188 EXIT();
14189
14190 return 0;
14191}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014192
14193#ifdef CFG80211_DEL_STA_V2
14194static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14195 struct net_device *dev,
14196 struct station_del_parameters *param)
14197#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014198#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14199static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14200 struct net_device *dev, const u8 *mac)
14201#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014202static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14203 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014204#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014205#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014206{
14207 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014208 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070014209
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014210 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014211
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014212#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014213 if (NULL == param) {
14214 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014215 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014216 return -EINVAL;
14217 }
14218
14219 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
14220 param->subtype, &delStaParams);
14221
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014222#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053014223 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014224 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014225#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014226 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
14227
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014228 vos_ssr_unprotect(__func__);
14229
14230 return ret;
14231}
14232
14233static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014234 struct net_device *dev,
14235#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14236 const u8 *mac,
14237#else
14238 u8 *mac,
14239#endif
14240 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014241{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014242 hdd_adapter_t *pAdapter;
14243 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014244 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014245#ifdef FEATURE_WLAN_TDLS
14246 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014247
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014248 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014249
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014250 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14251 if (NULL == pAdapter)
14252 {
14253 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14254 "%s: Adapter is NULL",__func__);
14255 return -EINVAL;
14256 }
14257 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14258 status = wlan_hdd_validate_context(pHddCtx);
14259 if (0 != status)
14260 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014261 return status;
14262 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014263
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014264 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14265 TRACE_CODE_HDD_CFG80211_ADD_STA,
14266 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014267 mask = params->sta_flags_mask;
14268
14269 set = params->sta_flags_set;
14270
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014271 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014272 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
14273 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014274
14275 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
14276 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014277 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014278 }
14279 }
14280#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014281 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014282 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014283}
14284
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014285#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14286static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14287 struct net_device *dev, const u8 *mac,
14288 struct station_parameters *params)
14289#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014290static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14291 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014292#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014293{
14294 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014295
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014296 vos_ssr_protect(__func__);
14297 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
14298 vos_ssr_unprotect(__func__);
14299
14300 return ret;
14301}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014302#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070014303
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014304static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070014305 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014306{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014307 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14308 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014309 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014310 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014311 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014312 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070014313
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014314 ENTER();
14315
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014316 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014317 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014318 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014319 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014320 return -EINVAL;
14321 }
14322
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014323 if (!pmksa) {
14324 hddLog(LOGE, FL("pmksa is NULL"));
14325 return -EINVAL;
14326 }
14327
14328 if (!pmksa->bssid || !pmksa->pmkid) {
14329 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
14330 pmksa->bssid, pmksa->pmkid);
14331 return -EINVAL;
14332 }
14333
14334 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
14335 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14336
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014337 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14338 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014339 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014340 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014341 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014342 }
14343
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014344 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014345 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14346
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014347 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
14348 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014349
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014350 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014351 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014352 &pmk_id, 1, FALSE);
14353
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014354 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14355 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
14356 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014357
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014358 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014359 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014360}
14361
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014362static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
14363 struct cfg80211_pmksa *pmksa)
14364{
14365 int ret;
14366
14367 vos_ssr_protect(__func__);
14368 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
14369 vos_ssr_unprotect(__func__);
14370
14371 return ret;
14372}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014373
Wilson Yang6507c4e2013-10-01 20:11:19 -070014374
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014375static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070014376 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014377{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014378 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14379 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014380 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014381 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014382
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014383 ENTER();
14384
Wilson Yang6507c4e2013-10-01 20:11:19 -070014385 /* Validate pAdapter */
14386 if (NULL == pAdapter)
14387 {
14388 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
14389 return -EINVAL;
14390 }
14391
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014392 if (!pmksa) {
14393 hddLog(LOGE, FL("pmksa is NULL"));
14394 return -EINVAL;
14395 }
14396
14397 if (!pmksa->bssid) {
14398 hddLog(LOGE, FL("pmksa->bssid is NULL"));
14399 return -EINVAL;
14400 }
14401
Kiet Lam98c46a12014-10-31 15:34:57 -070014402 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
14403 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14404
Wilson Yang6507c4e2013-10-01 20:11:19 -070014405 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14406 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014407 if (0 != status)
14408 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014409 return status;
14410 }
14411
14412 /*Retrieve halHandle*/
14413 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14414
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014415 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14416 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
14417 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014418 /* Delete the PMKID CSR cache */
14419 if (eHAL_STATUS_SUCCESS !=
14420 sme_RoamDelPMKIDfromCache(halHandle,
14421 pAdapter->sessionId, pmksa->bssid, FALSE)) {
14422 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
14423 MAC_ADDR_ARRAY(pmksa->bssid));
14424 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014425 }
14426
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014427 EXIT();
14428 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014429}
14430
Wilson Yang6507c4e2013-10-01 20:11:19 -070014431
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014432static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
14433 struct cfg80211_pmksa *pmksa)
14434{
14435 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014436
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014437 vos_ssr_protect(__func__);
14438 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
14439 vos_ssr_unprotect(__func__);
14440
14441 return ret;
14442
14443}
14444
14445static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014446{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014447 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14448 tHalHandle halHandle;
14449 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014450 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014451
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014452 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070014453
14454 /* Validate pAdapter */
14455 if (NULL == pAdapter)
14456 {
14457 hddLog(VOS_TRACE_LEVEL_ERROR,
14458 "%s: Invalid Adapter" ,__func__);
14459 return -EINVAL;
14460 }
14461
14462 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14463 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014464 if (0 != status)
14465 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014466 return status;
14467 }
14468
14469 /*Retrieve halHandle*/
14470 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14471
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014472 /* Flush the PMKID cache in CSR */
14473 if (eHAL_STATUS_SUCCESS !=
14474 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
14475 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
14476 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014477 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014478 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080014479 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014480}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014481
14482static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
14483{
14484 int ret;
14485
14486 vos_ssr_protect(__func__);
14487 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
14488 vos_ssr_unprotect(__func__);
14489
14490 return ret;
14491}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014492#endif
14493
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014494#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014495static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14496 struct net_device *dev,
14497 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014498{
14499 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14500 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014501 hdd_context_t *pHddCtx;
14502 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014503
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014504 ENTER();
14505
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014506 if (NULL == pAdapter)
14507 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014508 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014509 return -ENODEV;
14510 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014511 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14512 ret = wlan_hdd_validate_context(pHddCtx);
14513 if (0 != ret)
14514 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014515 return ret;
14516 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014517 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014518 if (NULL == pHddStaCtx)
14519 {
14520 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
14521 return -EINVAL;
14522 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014523
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014524 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14525 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
14526 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014527 // Added for debug on reception of Re-assoc Req.
14528 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
14529 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014530 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014531 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080014532 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014533 }
14534
14535#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080014536 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014537 ftie->ie_len);
14538#endif
14539
14540 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014541 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
14542 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014543 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014544
14545 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014546 return 0;
14547}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014548
14549static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14550 struct net_device *dev,
14551 struct cfg80211_update_ft_ies_params *ftie)
14552{
14553 int ret;
14554
14555 vos_ssr_protect(__func__);
14556 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
14557 vos_ssr_unprotect(__func__);
14558
14559 return ret;
14560}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014561#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014562
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014563#ifdef FEATURE_WLAN_SCAN_PNO
14564
14565void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
14566 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
14567{
14568 int ret;
14569 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
14570 hdd_context_t *pHddCtx;
14571
Nirav Shah80830bf2013-12-31 16:35:12 +053014572 ENTER();
14573
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014574 if (NULL == pAdapter)
14575 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014576 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014577 "%s: HDD adapter is Null", __func__);
14578 return ;
14579 }
14580
14581 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14582 if (NULL == pHddCtx)
14583 {
14584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14585 "%s: HDD context is Null!!!", __func__);
14586 return ;
14587 }
14588
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014589 spin_lock(&pHddCtx->schedScan_lock);
14590 if (TRUE == pHddCtx->isWiphySuspended)
14591 {
14592 pHddCtx->isSchedScanUpdatePending = TRUE;
14593 spin_unlock(&pHddCtx->schedScan_lock);
14594 hddLog(VOS_TRACE_LEVEL_INFO,
14595 "%s: Update cfg80211 scan database after it resume", __func__);
14596 return ;
14597 }
14598 spin_unlock(&pHddCtx->schedScan_lock);
14599
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014600 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
14601
14602 if (0 > ret)
14603 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
14604
14605 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14607 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014608}
14609
14610/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014611 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014612 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014613 */
14614static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
14615{
14616 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14617 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014618 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014619 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14620 int status = 0;
14621 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
14622
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014623 /* The current firmware design does not allow PNO during any
14624 * active sessions. Hence, determine the active sessions
14625 * and return a failure.
14626 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014627 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
14628 {
14629 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014630 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014631
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014632 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
14633 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
14634 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
14635 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
14636 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053014637 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014638 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014639 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014640 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014641 }
14642 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14643 pAdapterNode = pNext;
14644 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014645 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014646}
14647
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014648void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
14649{
14650 hdd_adapter_t *pAdapter = callbackContext;
14651 hdd_context_t *pHddCtx;
14652
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014653 ENTER();
14654
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014655 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
14656 {
14657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14658 FL("Invalid adapter or adapter has invalid magic"));
14659 return;
14660 }
14661
14662 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14663 if (0 != wlan_hdd_validate_context(pHddCtx))
14664 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014665 return;
14666 }
14667
c_hpothub53c45d2014-08-18 16:53:14 +053014668 if (VOS_STATUS_SUCCESS != status)
14669 {
14670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014671 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053014672 pHddCtx->isPnoEnable = FALSE;
14673 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014674
14675 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
14676 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014677 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014678}
14679
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014680/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014681 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
14682 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014683 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014684static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014685 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14686{
14687 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014688 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014689 hdd_context_t *pHddCtx;
14690 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014691 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053014692 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
14693 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014694 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
14695 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014696 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014697 hdd_config_t *pConfig = NULL;
14698 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014699
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014700 ENTER();
14701
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014702 if (NULL == pAdapter)
14703 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014704 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014705 "%s: HDD adapter is Null", __func__);
14706 return -ENODEV;
14707 }
14708
14709 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014710 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014711
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014712 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014713 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014714 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014715 }
14716
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014717 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014718 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14719 if (NULL == hHal)
14720 {
14721 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14722 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014723 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014724 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014725 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14726 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
14727 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053014728 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014729 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053014730 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014731 {
14732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14733 "%s: aborting the existing scan is unsuccessfull", __func__);
14734 return -EBUSY;
14735 }
14736
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014737 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014738 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014739 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014740 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014741 return -EBUSY;
14742 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014743
c_hpothu37f21312014-04-09 21:49:54 +053014744 if (TRUE == pHddCtx->isPnoEnable)
14745 {
14746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14747 FL("already PNO is enabled"));
14748 return -EBUSY;
14749 }
c_hpothu225aa7c2014-10-22 17:45:13 +053014750
14751 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
14752 {
14753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14754 "%s: abort ROC failed ", __func__);
14755 return -EBUSY;
14756 }
14757
c_hpothu37f21312014-04-09 21:49:54 +053014758 pHddCtx->isPnoEnable = TRUE;
14759
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014760 pnoRequest.enable = 1; /*Enable PNO */
14761 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014762
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014763 if (( !pnoRequest.ucNetworksCount ) ||
14764 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014765 {
14766 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014767 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014768 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014769 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014770 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014771 goto error;
14772 }
14773
14774 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
14775 {
14776 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014777 "%s: Incorrect number of channels %d",
14778 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014779 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014780 goto error;
14781 }
14782
14783 /* Framework provides one set of channels(all)
14784 * common for all saved profile */
14785 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
14786 channels_allowed, &num_channels_allowed))
14787 {
14788 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14789 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014790 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014791 goto error;
14792 }
14793 /* Checking each channel against allowed channel list */
14794 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053014795 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014796 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014797 char chList [(request->n_channels*5)+1];
14798 int len;
14799 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014800 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014801 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014802 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014803 if (request->channels[i]->hw_value == channels_allowed[indx])
14804 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014805 if ((!pConfig->enableDFSPnoChnlScan) &&
14806 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
14807 {
14808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14809 "%s : Dropping DFS channel : %d",
14810 __func__,channels_allowed[indx]);
14811 num_ignore_dfs_ch++;
14812 break;
14813 }
14814
Nirav Shah80830bf2013-12-31 16:35:12 +053014815 valid_ch[num_ch++] = request->channels[i]->hw_value;
14816 len += snprintf(chList+len, 5, "%d ",
14817 request->channels[i]->hw_value);
14818 break ;
14819 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014820 }
14821 }
Nirav Shah80830bf2013-12-31 16:35:12 +053014822 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014823
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014824 /*If all channels are DFS and dropped, then ignore the PNO request*/
14825 if (num_ignore_dfs_ch == request->n_channels)
14826 {
14827 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14828 "%s : All requested channels are DFS channels", __func__);
14829 ret = -EINVAL;
14830 goto error;
14831 }
14832 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014833
14834 pnoRequest.aNetworks =
14835 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14836 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014837 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014838 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14839 FL("failed to allocate memory aNetworks %u"),
14840 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14841 goto error;
14842 }
14843 vos_mem_zero(pnoRequest.aNetworks,
14844 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14845
14846 /* Filling per profile params */
14847 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
14848 {
14849 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014850 request->match_sets[i].ssid.ssid_len;
14851
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014852 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
14853 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014854 {
14855 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014856 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014857 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014858 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014859 goto error;
14860 }
14861
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014862 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014863 request->match_sets[i].ssid.ssid,
14864 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014865 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14866 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014867 i, pnoRequest.aNetworks[i].ssId.ssId);
14868 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
14869 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
14870 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014871
14872 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014873 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
14874 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014875
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014876 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014877 }
14878
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014879 for (i = 0; i < request->n_ssids; i++)
14880 {
14881 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014882 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014883 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014884 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014885 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014886 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014887 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014888 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014889 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014890 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014891 break;
14892 }
14893 j++;
14894 }
14895 }
14896 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14897 "Number of hidden networks being Configured = %d",
14898 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014899 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080014900 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014901
14902 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14903 if (pnoRequest.p24GProbeTemplate == NULL)
14904 {
14905 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14906 FL("failed to allocate memory p24GProbeTemplate %u"),
14907 SIR_PNO_MAX_PB_REQ_SIZE);
14908 goto error;
14909 }
14910
14911 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14912 if (pnoRequest.p5GProbeTemplate == NULL)
14913 {
14914 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14915 FL("failed to allocate memory p5GProbeTemplate %u"),
14916 SIR_PNO_MAX_PB_REQ_SIZE);
14917 goto error;
14918 }
14919
14920 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14921 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14922
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053014923 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
14924 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014925 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014926 pnoRequest.us24GProbeTemplateLen = request->ie_len;
14927 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
14928 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014929
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014930 pnoRequest.us5GProbeTemplateLen = request->ie_len;
14931 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
14932 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014933 }
14934
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014935 /* Driver gets only one time interval which is hardcoded in
14936 * supplicant for 10000ms. Taking power consumption into account 6 timers
14937 * will be used, Timervalue is increased exponentially i.e 10,20,40,
14938 * 80,160,320 secs. And number of scan cycle for each timer
14939 * is configurable through INI param gPNOScanTimerRepeatValue.
14940 * If it is set to 0 only one timer will be used and PNO scan cycle
14941 * will be repeated after each interval specified by supplicant
14942 * till PNO is disabled.
14943 */
14944 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014945 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014946 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014947 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014948 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
14949
14950 tempInterval = (request->interval)/1000;
14951 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14952 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
14953 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014954 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014955 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014956 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014957 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014958 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014959 tempInterval *= 2;
14960 }
14961 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014962 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014963
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014964 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014965
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014966 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014967 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
14968 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014969 pAdapter->pno_req_status = 0;
14970
Nirav Shah80830bf2013-12-31 16:35:12 +053014971 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14972 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014973 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
14974 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053014975
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014976 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014977 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014978 hdd_cfg80211_sched_scan_done_callback, pAdapter);
14979 if (eHAL_STATUS_SUCCESS != status)
14980 {
14981 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014982 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014983 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014984 goto error;
14985 }
14986
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014987 ret = wait_for_completion_timeout(
14988 &pAdapter->pno_comp_var,
14989 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
14990 if (0 >= ret)
14991 {
14992 // Did not receive the response for PNO enable in time.
14993 // Assuming the PNO enable was success.
14994 // Returning error from here, because we timeout, results
14995 // in side effect of Wifi (Wifi Setting) not to work.
14996 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14997 FL("Timed out waiting for PNO to be Enabled"));
14998 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014999 }
15000
15001 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053015002 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015003
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015004error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015005 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15006 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053015007 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015008 if (pnoRequest.aNetworks)
15009 vos_mem_free(pnoRequest.aNetworks);
15010 if (pnoRequest.p24GProbeTemplate)
15011 vos_mem_free(pnoRequest.p24GProbeTemplate);
15012 if (pnoRequest.p5GProbeTemplate)
15013 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015014
15015 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015016 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015017}
15018
15019/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015020 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
15021 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015022 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015023static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
15024 struct net_device *dev, struct cfg80211_sched_scan_request *request)
15025{
15026 int ret;
15027
15028 vos_ssr_protect(__func__);
15029 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
15030 vos_ssr_unprotect(__func__);
15031
15032 return ret;
15033}
15034
15035/*
15036 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
15037 * Function to disable PNO
15038 */
15039static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015040 struct net_device *dev)
15041{
15042 eHalStatus status = eHAL_STATUS_FAILURE;
15043 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15044 hdd_context_t *pHddCtx;
15045 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015046 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015047 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015048
15049 ENTER();
15050
15051 if (NULL == pAdapter)
15052 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015053 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015054 "%s: HDD adapter is Null", __func__);
15055 return -ENODEV;
15056 }
15057
15058 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015059
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015060 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015061 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053015062 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015063 "%s: HDD context is Null", __func__);
15064 return -ENODEV;
15065 }
15066
15067 /* The return 0 is intentional when isLogpInProgress and
15068 * isLoadUnloadInProgress. We did observe a crash due to a return of
15069 * failure in sched_scan_stop , especially for a case where the unload
15070 * of the happens at the same time. The function __cfg80211_stop_sched_scan
15071 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
15072 * success. If it returns a failure , then its next invocation due to the
15073 * clean up of the second interface will have the dev pointer corresponding
15074 * to the first one leading to a crash.
15075 */
15076 if (pHddCtx->isLogpInProgress)
15077 {
15078 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15079 "%s: LOGP in Progress. Ignore!!!", __func__);
15080 return ret;
15081 }
15082
Mihir Shete18156292014-03-11 15:38:30 +053015083 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015084 {
15085 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15086 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15087 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015088 }
15089
15090 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
15091 if (NULL == hHal)
15092 {
15093 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15094 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015095 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015096 }
15097
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015098 pnoRequest.enable = 0; /* Disable PNO */
15099 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015100
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053015101 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15102 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
15103 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053015104 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015105 pAdapter->sessionId,
15106 NULL, pAdapter);
15107 if (eHAL_STATUS_SUCCESS != status)
15108 {
15109 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15110 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015111 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015112 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015113 }
c_hpothu37f21312014-04-09 21:49:54 +053015114 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015115
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015116error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053015117 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053015118 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015119
15120 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053015121 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015122}
15123
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053015124/*
15125 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
15126 * NL interface to disable PNO
15127 */
15128static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
15129 struct net_device *dev)
15130{
15131 int ret;
15132
15133 vos_ssr_protect(__func__);
15134 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
15135 vos_ssr_unprotect(__func__);
15136
15137 return ret;
15138}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053015139#endif /*FEATURE_WLAN_SCAN_PNO*/
15140
15141
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015142#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015143#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015144static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15145 struct net_device *dev,
15146 u8 *peer, u8 action_code,
15147 u8 dialog_token,
15148 u16 status_code, u32 peer_capability,
15149 const u8 *buf, size_t len)
15150#else /* TDLS_MGMT_VERSION2 */
15151#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
15152static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15153 struct net_device *dev,
15154 const u8 *peer, u8 action_code,
15155 u8 dialog_token, u16 status_code,
15156 u32 peer_capability, bool initiator,
15157 const u8 *buf, size_t len)
15158#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
15159static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15160 struct net_device *dev,
15161 const u8 *peer, u8 action_code,
15162 u8 dialog_token, u16 status_code,
15163 u32 peer_capability, const u8 *buf,
15164 size_t len)
15165#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
15166static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15167 struct net_device *dev,
15168 u8 *peer, u8 action_code,
15169 u8 dialog_token,
15170 u16 status_code, u32 peer_capability,
15171 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015172#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015173static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15174 struct net_device *dev,
15175 u8 *peer, u8 action_code,
15176 u8 dialog_token,
15177 u16 status_code, const u8 *buf,
15178 size_t len)
15179#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015180#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015181{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015182 hdd_adapter_t *pAdapter;
15183 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015184 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070015185 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080015186 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070015187 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015188 int ret;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015189#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015190 u32 peer_capability = 0;
15191#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015192 tANI_U16 numCurrTdlsPeers;
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015193 hdd_station_ctx_t *pHddStaCtx = NULL;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015194
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015195 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15196 if (NULL == pAdapter)
15197 {
15198 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15199 "%s: Adapter is NULL",__func__);
15200 return -EINVAL;
15201 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015202 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15203 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
15204 pAdapter->sessionId, action_code));
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015205
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015206 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015207 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015208 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015209 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015210 "Invalid arguments");
15211 return -EINVAL;
15212 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015213
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015214 if (pHddCtx->isLogpInProgress)
15215 {
15216 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15217 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053015218 wlan_hdd_tdls_set_link_status(pAdapter,
15219 peer,
15220 eTDLS_LINK_IDLE,
15221 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015222 return -EBUSY;
15223 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015224
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015225 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
15226 {
15227 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15228 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15229 return -EAGAIN;
15230 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015231
Hoonki Lee27511902013-03-14 18:19:06 -070015232 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015233 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015234 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015235 "%s: TDLS mode is disabled OR not enabled in FW."
15236 MAC_ADDRESS_STR " action %d declined.",
15237 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015238 return -ENOTSUPP;
15239 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015240
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015241 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
15242
15243 if( NULL == pHddStaCtx )
15244 {
15245 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15246 "%s: HDD station context NULL ",__func__);
15247 return -EINVAL;
15248 }
15249
15250 /* STA should be connected and authenticated
15251 * before sending any TDLS frames
15252 */
15253 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
15254 (FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
15255 {
15256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15257 "STA is not connected or unauthenticated. "
15258 "connState %u, uIsAuthenticated %u",
15259 pHddStaCtx->conn_info.connState,
15260 pHddStaCtx->conn_info.uIsAuthenticated);
15261 return -EAGAIN;
15262 }
15263
Hoonki Lee27511902013-03-14 18:19:06 -070015264 /* other than teardown frame, other mgmt frames are not sent if disabled */
15265 if (SIR_MAC_TDLS_TEARDOWN != action_code)
15266 {
15267 /* if tdls_mode is disabled to respond to peer's request */
15268 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
15269 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015270 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015271 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015272 " TDLS mode is disabled. action %d declined.",
15273 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070015274
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015275 return -ENOTSUPP;
Hoonki Lee27511902013-03-14 18:19:06 -070015276 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053015277
15278 if (vos_max_concurrent_connections_reached())
15279 {
15280 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15281 return -EINVAL;
15282 }
Hoonki Lee27511902013-03-14 18:19:06 -070015283 }
15284
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015285 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
15286 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053015287 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015288 {
15289 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015290 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015291 " TDLS setup is ongoing. action %d declined.",
15292 __func__, MAC_ADDR_ARRAY(peer), action_code);
15293 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015294 }
15295 }
15296
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015297 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
15298 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080015299 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015300 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15301 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015302 {
15303 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
15304 we return error code at 'add_station()'. Hence we have this
15305 check again in addtion to add_station().
15306 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015307 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015308 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015309 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15310 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015311 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
15312 __func__, MAC_ADDR_ARRAY(peer), action_code,
15313 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053015314 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080015315 }
15316 else
15317 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015318 /* maximum reached. tweak to send error code to peer and return
15319 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015320 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015321 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15322 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015323 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
15324 __func__, MAC_ADDR_ARRAY(peer), status_code,
15325 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070015326 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015327 /* fall through to send setup resp with failure status
15328 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015329 }
15330 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015331 else
15332 {
15333 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053015334 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015335 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015336 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015337 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015338 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
15339 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015340 return -EPERM;
15341 }
15342 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015343 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015344
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015345 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015346 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015347 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
15348 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015349
Hoonki Leea34dd892013-02-05 22:56:02 -080015350 /*Except teardown responder will not be used so just make 0*/
15351 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015352 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080015353 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015354
15355 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015356 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015357
15358 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
15359 responder = pTdlsPeer->is_responder;
15360 else
Hoonki Leea34dd892013-02-05 22:56:02 -080015361 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015362 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015363 "%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 -070015364 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
15365 dialog_token, status_code, len);
15366 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080015367 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015368 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015369
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015370 /* For explicit trigger of DIS_REQ come out of BMPS for
15371 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070015372 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015373 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
15374 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070015375 {
15376 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
15377 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015378 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015379 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015380 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
15381 if (status != VOS_STATUS_SUCCESS) {
15382 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
15383 }
Hoonki Lee14621352013-04-16 17:51:19 -070015384 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015385 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015386 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015387 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
15388 }
15389 }
Hoonki Lee14621352013-04-16 17:51:19 -070015390 }
15391
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015392 /* make sure doesn't call send_mgmt() while it is pending */
15393 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
15394 {
15395 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015396 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015397 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015398 ret = -EBUSY;
15399 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015400 }
15401
15402 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015403 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
15404
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015405 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter),
15406 pAdapter->sessionId, peer, action_code, dialog_token,
15407 status_code, peer_capability, (tANI_U8 *)buf, len,
15408 responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015409
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015410 if (VOS_STATUS_SUCCESS != status)
15411 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015412 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15413 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015414 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015415 ret = -EINVAL;
15416 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015417 }
15418
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015419 if ((SIR_MAC_TDLS_DIS_REQ == action_code) ||
15420 (SIR_MAC_TDLS_DIS_RSP == action_code))
15421 {
15422 /* for DIS_REQ/DIS_RSP, supplicant don't consider the return status.
15423 * So we no need to wait for tdls_mgmt_comp for sending ack status.
15424 */
15425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15426 "%s: tx done for frm %u", __func__, action_code);
15427 return 0;
15428 }
15429
15430 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15431 "%s: Wait for tdls_mgmt_comp. Timeout %u ms", __func__,
15432 WAIT_TIME_TDLS_MGMT);
15433
Hoonki Leed37cbb32013-04-20 00:31:14 -070015434 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
15435 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
15436
15437 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015438 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070015439 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015440 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070015441 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015442 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080015443
15444 if (pHddCtx->isLogpInProgress)
15445 {
15446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15447 "%s: LOGP in Progress. Ignore!!!", __func__);
15448 return -EAGAIN;
15449 }
15450
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015451 ret = -EINVAL;
15452 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015453 }
Ganesh Kondabattini8d0d35b2015-08-20 15:39:09 +053015454 else
15455 {
15456 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15457 "%s: Mgmt Tx Completion status %ld TxCompletion %u",
15458 __func__, rc, pAdapter->mgmtTxCompletionStatus);
15459 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015460
Gopichand Nakkala05922802013-03-14 12:23:19 -070015461 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070015462 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015463 ret = max_sta_failed;
15464 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070015465 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015466
Hoonki Leea34dd892013-02-05 22:56:02 -080015467 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
15468 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015469 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015470 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15471 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015472 }
15473 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
15474 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015475 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015476 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15477 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015478 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015479
15480 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015481
15482tx_failed:
15483 /* add_station will be called before sending TDLS_SETUP_REQ and
15484 * TDLS_SETUP_RSP and as part of add_station driver will enable
15485 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
15486 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
15487 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
15488 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
15489 */
15490
15491 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
15492 (SIR_MAC_TDLS_SETUP_RSP == action_code))
15493 wlan_hdd_tdls_check_bmps(pAdapter);
15494 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015495}
15496
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015497#if TDLS_MGMT_VERSION2
15498static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15499 u8 *peer, u8 action_code, u8 dialog_token,
15500 u16 status_code, u32 peer_capability,
15501 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015502#else /* TDLS_MGMT_VERSION2 */
15503#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
15504static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15505 struct net_device *dev,
15506 const u8 *peer, u8 action_code,
15507 u8 dialog_token, u16 status_code,
15508 u32 peer_capability, bool initiator,
15509 const u8 *buf, size_t len)
15510#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15511static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15512 struct net_device *dev,
15513 const u8 *peer, u8 action_code,
15514 u8 dialog_token, u16 status_code,
15515 u32 peer_capability, const u8 *buf,
15516 size_t len)
15517#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
15518static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15519 struct net_device *dev,
15520 u8 *peer, u8 action_code,
15521 u8 dialog_token,
15522 u16 status_code, u32 peer_capability,
15523 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015524#else
15525static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15526 u8 *peer, u8 action_code, u8 dialog_token,
15527 u16 status_code, const u8 *buf, size_t len)
15528#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015529#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015530{
15531 int ret;
15532
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015533 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015534#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015535 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15536 dialog_token, status_code,
15537 peer_capability, buf, len);
15538#else /* TDLS_MGMT_VERSION2 */
15539#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
15540 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15541 dialog_token, status_code,
15542 peer_capability, initiator,
15543 buf, len);
15544#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
15545 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15546 dialog_token, status_code,
15547 peer_capability, buf, len);
15548#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
15549 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15550 dialog_token, status_code,
15551 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015552#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015553 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15554 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015555#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015556#endif
15557 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015558
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015559 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015560}
Atul Mittal115287b2014-07-08 13:26:33 +053015561
15562int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015563#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15564 const u8 *peer,
15565#else
Atul Mittal115287b2014-07-08 13:26:33 +053015566 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015567#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015568 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053015569 cfg80211_exttdls_callback callback)
15570{
15571
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015572 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053015573 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015574 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053015575 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15576 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
15577 __func__, MAC_ADDR_ARRAY(peer));
15578
15579 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
15580 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
15581
15582 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015583 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
15584 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
15585 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053015586 return -ENOTSUPP;
15587 }
15588
15589 /* To cater the requirement of establishing the TDLS link
15590 * irrespective of the data traffic , get an entry of TDLS peer.
15591 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015592 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015593 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
15594 if (pTdlsPeer == NULL) {
15595 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15596 "%s: peer " MAC_ADDRESS_STR " not existing",
15597 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015598 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015599 return -EINVAL;
15600 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015601 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015602
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053015603 /* check FW TDLS Off Channel capability */
15604 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053015605 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053015606 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015607 {
15608 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
15609 pTdlsPeer->peerParams.global_operating_class =
15610 tdls_peer_params->global_operating_class;
15611 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
15612 pTdlsPeer->peerParams.min_bandwidth_kbps =
15613 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015614 /* check configured channel is valid, non dfs and
15615 * not current operating channel */
15616 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
15617 tdls_peer_params->channel)) &&
15618 (pHddStaCtx) &&
15619 (tdls_peer_params->channel !=
15620 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015621 {
15622 pTdlsPeer->isOffChannelConfigured = TRUE;
15623 }
15624 else
15625 {
15626 pTdlsPeer->isOffChannelConfigured = FALSE;
15627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15628 "%s: Configured Tdls Off Channel is not valid", __func__);
15629
15630 }
15631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015632 "%s: tdls_off_channel %d isOffChannelConfigured %d "
15633 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015634 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015635 pTdlsPeer->isOffChannelConfigured,
15636 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015637 }
15638 else
15639 {
15640 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053015641 "%s: TDLS off channel FW capability %d, "
15642 "host capab %d or Invalid TDLS Peer Params", __func__,
15643 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
15644 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015645 }
15646
Atul Mittal115287b2014-07-08 13:26:33 +053015647 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
15648
15649 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15650 " %s TDLS Add Force Peer Failed",
15651 __func__);
15652 return -EINVAL;
15653 }
15654 /*EXT TDLS*/
15655
15656 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
15657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15658 " %s TDLS set callback Failed",
15659 __func__);
15660 return -EINVAL;
15661 }
15662
15663 return(0);
15664
15665}
15666
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015667int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
15668#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15669 const u8 *peer
15670#else
15671 u8 *peer
15672#endif
15673)
Atul Mittal115287b2014-07-08 13:26:33 +053015674{
15675
15676 hddTdlsPeer_t *pTdlsPeer;
15677 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15679 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
15680 __func__, MAC_ADDR_ARRAY(peer));
15681
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015682 if (0 != wlan_hdd_validate_context(pHddCtx)) {
15683 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
15684 return -EINVAL;
15685 }
15686
Atul Mittal115287b2014-07-08 13:26:33 +053015687 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
15688 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
15689
15690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015691 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
15692 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
15693 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053015694 return -ENOTSUPP;
15695 }
15696
15697
15698 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15699
15700 if ( NULL == pTdlsPeer ) {
15701 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015702 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053015703 __func__, MAC_ADDR_ARRAY(peer));
15704 return -EINVAL;
15705 }
15706 else {
15707 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
15708 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015709 /* if channel switch is configured, reset
15710 the channel for this peer */
15711 if (TRUE == pTdlsPeer->isOffChannelConfigured)
15712 {
15713 pTdlsPeer->peerParams.channel = 0;
15714 pTdlsPeer->isOffChannelConfigured = FALSE;
15715 }
Atul Mittal115287b2014-07-08 13:26:33 +053015716 }
15717
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015718 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
15719 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053015720 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015721 }
Atul Mittal115287b2014-07-08 13:26:33 +053015722
15723 /*EXT TDLS*/
15724
15725 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
15726
15727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15728 " %s TDLS set callback Failed",
15729 __func__);
15730 return -EINVAL;
15731 }
15732 return(0);
15733
15734}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015735static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015736#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15737 const u8 *peer,
15738#else
15739 u8 *peer,
15740#endif
15741 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015742{
15743 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15744 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015745 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015746 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015747
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015748 ENTER();
15749
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015750 if (!pAdapter) {
15751 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
15752 return -EINVAL;
15753 }
15754
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015755 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15756 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
15757 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015758 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015759 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015760 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070015761 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015762 return -EINVAL;
15763 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015764
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015765 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015766 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015767 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015768 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015769 }
15770
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015771
15772 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015773 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015774 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015775 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015776 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
15777 "Cannot process TDLS commands",
15778 pHddCtx->cfg_ini->fEnableTDLSSupport,
15779 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015780 return -ENOTSUPP;
15781 }
15782
15783 switch (oper) {
15784 case NL80211_TDLS_ENABLE_LINK:
15785 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015786 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015787 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015788 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053015789 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015790 tANI_U16 numCurrTdlsPeers = 0;
15791 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015792 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015793
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015794 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15795 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
15796 __func__, MAC_ADDR_ARRAY(peer));
Sunil Dutt41de4e22013-11-14 18:09:02 +053015797 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053015798 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053015799 if ( NULL == pTdlsPeer ) {
15800 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15801 " (oper %d) not exsting. ignored",
15802 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15803 return -EINVAL;
15804 }
15805
15806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15807 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15808 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15809 "NL80211_TDLS_ENABLE_LINK");
15810
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070015811 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
15812 {
15813 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
15814 MAC_ADDRESS_STR " failed",
15815 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
15816 return -EINVAL;
15817 }
15818
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053015819 /* before starting tdls connection, set tdls
15820 * off channel established status to default value */
15821 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015822 /* TDLS Off Channel, Disable tdls channel switch,
15823 when there are more than one tdls link */
15824 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053015825 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015826 {
15827 /* get connected peer and send disable tdls off chan */
15828 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015829 if ((connPeer) &&
15830 (connPeer->isOffChannelSupported == TRUE) &&
15831 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015832 {
15833 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15834 "%s: More then one peer connected, Disable "
15835 "TDLS channel switch", __func__);
15836
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015837 connPeer->isOffChannelEstablished = FALSE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015838 ret = sme_SendTdlsChanSwitchReq(
15839 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015840 pAdapter->sessionId,
15841 connPeer->peerMac,
15842 connPeer->peerParams.channel,
15843 TDLS_OFF_CHANNEL_BW_OFFSET,
15844 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015845 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015846 hddLog(VOS_TRACE_LEVEL_ERROR,
15847 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015848 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015849 }
15850 else
15851 {
15852 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15853 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015854 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015855 "isOffChannelConfigured %d",
15856 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015857 (connPeer ? (connPeer->isOffChannelSupported)
15858 : -1),
15859 (connPeer ? (connPeer->isOffChannelConfigured)
15860 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015861 }
15862 }
15863
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015864 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015865 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015866 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053015867
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015868 if (0 != wlan_hdd_tdls_get_link_establish_params(
15869 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015870 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015871 return -EINVAL;
15872 }
15873 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015874
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015875 ret = sme_SendTdlsLinkEstablishParams(
15876 WLAN_HDD_GET_HAL_CTX(pAdapter),
15877 pAdapter->sessionId, peer,
15878 &tdlsLinkEstablishParams);
15879 if (ret != VOS_STATUS_SUCCESS) {
15880 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
15881 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015882 /* Send TDLS peer UAPSD capabilities to the firmware and
15883 * register with the TL on after the response for this operation
15884 * is received .
15885 */
15886 ret = wait_for_completion_interruptible_timeout(
15887 &pAdapter->tdls_link_establish_req_comp,
15888 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
15889 if (ret <= 0)
15890 {
15891 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015892 FL("Link Establish Request Failed Status %ld"),
15893 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015894 return -EINVAL;
15895 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015896 }
Atul Mittal115287b2014-07-08 13:26:33 +053015897 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15898 eTDLS_LINK_CONNECTED,
15899 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053015900 staDesc.ucSTAId = pTdlsPeer->staId;
15901 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015902 ret = WLANTL_UpdateTdlsSTAClient(
15903 pHddCtx->pvosContext,
15904 &staDesc);
15905 if (ret != VOS_STATUS_SUCCESS) {
15906 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
15907 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053015908
Gopichand Nakkala471708b2013-06-04 20:03:01 +053015909 /* Mark TDLS client Authenticated .*/
15910 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
15911 pTdlsPeer->staId,
15912 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015913 if (VOS_STATUS_SUCCESS == status)
15914 {
Hoonki Lee14621352013-04-16 17:51:19 -070015915 if (pTdlsPeer->is_responder == 0)
15916 {
15917 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
15918
15919 wlan_hdd_tdls_timer_restart(pAdapter,
15920 &pTdlsPeer->initiatorWaitTimeoutTimer,
15921 WAIT_TIME_TDLS_INITIATOR);
15922 /* suspend initiator TX until it receives direct packet from the
15923 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015924 ret = WLANTL_SuspendDataTx(
15925 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15926 &staId, NULL);
15927 if (ret != VOS_STATUS_SUCCESS) {
15928 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
15929 }
Hoonki Lee14621352013-04-16 17:51:19 -070015930 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015931
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015932 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015933 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015934 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015935 suppChannelLen =
15936 tdlsLinkEstablishParams.supportedChannelsLen;
15937
15938 if ((suppChannelLen > 0) &&
15939 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
15940 {
15941 tANI_U8 suppPeerChannel = 0;
15942 int i = 0;
15943 for (i = 0U; i < suppChannelLen; i++)
15944 {
15945 suppPeerChannel =
15946 tdlsLinkEstablishParams.supportedChannels[i];
15947
15948 pTdlsPeer->isOffChannelSupported = FALSE;
15949 if (suppPeerChannel ==
15950 pTdlsPeer->peerParams.channel)
15951 {
15952 pTdlsPeer->isOffChannelSupported = TRUE;
15953 break;
15954 }
15955 }
15956 }
15957 else
15958 {
15959 pTdlsPeer->isOffChannelSupported = FALSE;
15960 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015961 }
15962 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15963 "%s: TDLS channel switch request for channel "
15964 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015965 "%d isOffChannelSupported %d", __func__,
15966 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015967 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015968 suppChannelLen,
15969 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015970
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015971 /* TDLS Off Channel, Enable tdls channel switch,
15972 when their is only one tdls link and it supports */
15973 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15974 if ((numCurrTdlsPeers == 1) &&
15975 (TRUE == pTdlsPeer->isOffChannelSupported) &&
15976 (TRUE == pTdlsPeer->isOffChannelConfigured))
15977 {
15978 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15979 "%s: Send TDLS channel switch request for channel %d",
15980 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015981
15982 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015983 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
15984 pAdapter->sessionId,
15985 pTdlsPeer->peerMac,
15986 pTdlsPeer->peerParams.channel,
15987 TDLS_OFF_CHANNEL_BW_OFFSET,
15988 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015989 if (ret != VOS_STATUS_SUCCESS) {
15990 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
15991 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015992 }
15993 else
15994 {
15995 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15996 "%s: TDLS channel switch request not sent"
15997 " numCurrTdlsPeers %d "
15998 "isOffChannelSupported %d "
15999 "isOffChannelConfigured %d",
16000 __func__, numCurrTdlsPeers,
16001 pTdlsPeer->isOffChannelSupported,
16002 pTdlsPeer->isOffChannelConfigured);
16003 }
16004
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070016005 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016006 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016007
16008 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016009 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
16010 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016011 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016012 int ac;
16013 uint8 ucAc[4] = { WLANTL_AC_VO,
16014 WLANTL_AC_VI,
16015 WLANTL_AC_BK,
16016 WLANTL_AC_BE };
16017 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
16018 for(ac=0; ac < 4; ac++)
16019 {
16020 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
16021 pTdlsPeer->staId, ucAc[ac],
16022 tlTid[ac], tlTid[ac], 0, 0,
16023 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016024 if (status != VOS_STATUS_SUCCESS) {
16025 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
16026 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053016027 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053016028 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016029 }
16030
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016031 }
16032 break;
16033 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080016034 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016035 tANI_U16 numCurrTdlsPeers = 0;
16036 hddTdlsPeer_t *connPeer = NULL;
16037
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016038 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16039 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
16040 __func__, MAC_ADDR_ARRAY(peer));
16041
Sunil Dutt41de4e22013-11-14 18:09:02 +053016042 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
16043
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016044
Sunil Dutt41de4e22013-11-14 18:09:02 +053016045 if ( NULL == pTdlsPeer ) {
16046 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
16047 " (oper %d) not exsting. ignored",
16048 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
16049 return -EINVAL;
16050 }
16051
16052 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16053 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
16054 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
16055 "NL80211_TDLS_DISABLE_LINK");
16056
Hoonki Lee5305c3a2013-04-29 23:28:59 -070016057 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080016058 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016059 long status;
16060
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053016061 /* set tdls off channel status to false for this peer */
16062 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053016063 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
16064 eTDLS_LINK_TEARING,
16065 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
16066 eTDLS_LINK_UNSPECIFIED:
16067 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016068 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
16069
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016070 status = sme_DeleteTdlsPeerSta(
16071 WLAN_HDD_GET_HAL_CTX(pAdapter),
16072 pAdapter->sessionId, peer );
16073 if (status != VOS_STATUS_SUCCESS) {
16074 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
16075 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016076
16077 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
16078 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053016079 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053016080 eTDLS_LINK_IDLE,
16081 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016082 if (status <= 0)
16083 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070016084 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16085 "%s: Del station failed status %ld",
16086 __func__, status);
16087 return -EPERM;
16088 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016089
16090 /* TDLS Off Channel, Enable tdls channel switch,
16091 when their is only one tdls link and it supports */
16092 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
16093 if (numCurrTdlsPeers == 1)
16094 {
16095 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
16096 if ((connPeer) &&
16097 (connPeer->isOffChannelSupported == TRUE) &&
16098 (connPeer->isOffChannelConfigured == TRUE))
16099 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016100 connPeer->isOffChannelEstablished = TRUE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053016101 status = sme_SendTdlsChanSwitchReq(
16102 WLAN_HDD_GET_HAL_CTX(pAdapter),
16103 pAdapter->sessionId,
16104 connPeer->peerMac,
16105 connPeer->peerParams.channel,
16106 TDLS_OFF_CHANNEL_BW_OFFSET,
16107 TDLS_CHANNEL_SWITCH_ENABLE);
16108 if (status != VOS_STATUS_SUCCESS) {
16109 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
16110 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016111 }
16112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16113 "%s: TDLS channel switch "
16114 "isOffChannelSupported %d "
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016115 "isOffChannelConfigured %d "
16116 "isOffChannelEstablished %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016117 __func__,
16118 (connPeer ? connPeer->isOffChannelSupported : -1),
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053016119 (connPeer ? connPeer->isOffChannelConfigured : -1),
16120 (connPeer ? connPeer->isOffChannelEstablished : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016121 }
16122 else
16123 {
16124 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16125 "%s: TDLS channel switch request not sent "
16126 "numCurrTdlsPeers %d ",
16127 __func__, numCurrTdlsPeers);
16128 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080016129 }
16130 else
16131 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016132 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16133 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080016134 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080016135 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070016136 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016137 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053016138 {
Atul Mittal115287b2014-07-08 13:26:33 +053016139 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053016140
Atul Mittal115287b2014-07-08 13:26:33 +053016141 if (0 != status)
16142 {
16143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016144 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053016145 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053016146 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053016147 break;
16148 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016149 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053016150 {
Atul Mittal115287b2014-07-08 13:26:33 +053016151 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
16152 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053016153 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053016154 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053016155
Atul Mittal115287b2014-07-08 13:26:33 +053016156 if (0 != status)
16157 {
16158 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016159 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053016160 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053016161 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053016162 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053016163 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016164 case NL80211_TDLS_DISCOVERY_REQ:
16165 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016166 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053016167 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016168 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016169 return -ENOTSUPP;
16170 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016171 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16172 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016173 return -ENOTSUPP;
16174 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016175
16176 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016177 return 0;
16178}
Chilam NG571c65a2013-01-19 12:27:36 +053016179
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016180static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016181#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
16182 const u8 *peer,
16183#else
16184 u8 *peer,
16185#endif
16186 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016187{
16188 int ret;
16189
16190 vos_ssr_protect(__func__);
16191 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
16192 vos_ssr_unprotect(__func__);
16193
16194 return ret;
16195}
16196
Chilam NG571c65a2013-01-19 12:27:36 +053016197int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
16198 struct net_device *dev, u8 *peer)
16199{
Arif Hussaina7c8e412013-11-20 11:06:42 -080016200 hddLog(VOS_TRACE_LEVEL_INFO,
16201 "tdls send discover req: "MAC_ADDRESS_STR,
16202 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053016203
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016204#if TDLS_MGMT_VERSION2
16205 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16206 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16207#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016208#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
16209 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16210 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
16211#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
16212 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16213 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16214#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
16215 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16216 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
16217#else
Chilam NG571c65a2013-01-19 12:27:36 +053016218 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
16219 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053016220#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053016221#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053016222}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016223#endif
16224
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016225#ifdef WLAN_FEATURE_GTK_OFFLOAD
16226/*
16227 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
16228 * Callback rountine called upon receiving response for
16229 * get offload info
16230 */
16231void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
16232 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
16233{
16234
16235 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016236 tANI_U8 tempReplayCounter[8];
16237 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016238
16239 ENTER();
16240
16241 if (NULL == pAdapter)
16242 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016243 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016244 "%s: HDD adapter is Null", __func__);
16245 return ;
16246 }
16247
16248 if (NULL == pGtkOffloadGetInfoRsp)
16249 {
16250 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16251 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
16252 return ;
16253 }
16254
16255 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
16256 {
16257 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16258 "%s: wlan Failed to get replay counter value",
16259 __func__);
16260 return ;
16261 }
16262
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016263 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16264 /* Update replay counter */
16265 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
16266 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16267
16268 {
16269 /* changing from little to big endian since supplicant
16270 * works on big endian format
16271 */
16272 int i;
16273 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16274
16275 for (i = 0; i < 8; i++)
16276 {
16277 tempReplayCounter[7-i] = (tANI_U8)p[i];
16278 }
16279 }
16280
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016281 /* Update replay counter to NL */
16282 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016283 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016284}
16285
16286/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016287 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016288 * This function is used to offload GTK rekeying job to the firmware.
16289 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016290int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016291 struct cfg80211_gtk_rekey_data *data)
16292{
16293 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16294 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16295 hdd_station_ctx_t *pHddStaCtx;
16296 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016297 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016298 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016299 eHalStatus status = eHAL_STATUS_FAILURE;
16300
16301 ENTER();
16302
16303 if (NULL == pAdapter)
16304 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016305 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016306 "%s: HDD adapter is Null", __func__);
16307 return -ENODEV;
16308 }
16309
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016310 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16311 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
16312 pAdapter->sessionId, pAdapter->device_mode));
16313
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016314 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016315 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016316 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016317 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016318 }
16319
16320 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16321 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16322 if (NULL == hHal)
16323 {
16324 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16325 "%s: HAL context is Null!!!", __func__);
16326 return -EAGAIN;
16327 }
16328
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016329 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
16330 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
16331 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
16332 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016333 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016334 {
16335 /* changing from big to little endian since driver
16336 * works on little endian format
16337 */
16338 tANI_U8 *p =
16339 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
16340 int i;
16341
16342 for (i = 0; i < 8; i++)
16343 {
16344 p[7-i] = data->replay_ctr[i];
16345 }
16346 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016347
16348 if (TRUE == pHddCtx->hdd_wlan_suspended)
16349 {
16350 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016351 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
16352 sizeof (tSirGtkOffloadParams));
16353 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016354 pAdapter->sessionId);
16355
16356 if (eHAL_STATUS_SUCCESS != status)
16357 {
16358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16359 "%s: sme_SetGTKOffload failed, returned %d",
16360 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016361
16362 /* Need to clear any trace of key value in the memory.
16363 * Thus zero out the memory even though it is local
16364 * variable.
16365 */
16366 vos_mem_zero(&hddGtkOffloadReqParams,
16367 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016368 return status;
16369 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16371 "%s: sme_SetGTKOffload successfull", __func__);
16372 }
16373 else
16374 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016375 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16376 "%s: wlan not suspended GTKOffload request is stored",
16377 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016378 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016379
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016380 /* Need to clear any trace of key value in the memory.
16381 * Thus zero out the memory even though it is local
16382 * variable.
16383 */
16384 vos_mem_zero(&hddGtkOffloadReqParams,
16385 sizeof(hddGtkOffloadReqParams));
16386
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016387 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016388 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016389}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016390
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016391int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
16392 struct cfg80211_gtk_rekey_data *data)
16393{
16394 int ret;
16395
16396 vos_ssr_protect(__func__);
16397 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
16398 vos_ssr_unprotect(__func__);
16399
16400 return ret;
16401}
16402#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016403/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016404 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016405 * This function is used to set access control policy
16406 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016407static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
16408 struct net_device *dev,
16409 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016410{
16411 int i;
16412 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16413 hdd_hostapd_state_t *pHostapdState;
16414 tsap_Config_t *pConfig;
16415 v_CONTEXT_t pVosContext = NULL;
16416 hdd_context_t *pHddCtx;
16417 int status;
16418
16419 ENTER();
16420
16421 if (NULL == pAdapter)
16422 {
16423 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16424 "%s: HDD adapter is Null", __func__);
16425 return -ENODEV;
16426 }
16427
16428 if (NULL == params)
16429 {
16430 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16431 "%s: params is Null", __func__);
16432 return -EINVAL;
16433 }
16434
16435 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16436 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016437 if (0 != status)
16438 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016439 return status;
16440 }
16441
16442 pVosContext = pHddCtx->pvosContext;
16443 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
16444
16445 if (NULL == pHostapdState)
16446 {
16447 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16448 "%s: pHostapdState is Null", __func__);
16449 return -EINVAL;
16450 }
16451
16452 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
16453 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016454 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16455 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
16456 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016457
16458 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
16459 {
16460 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
16461
16462 /* default value */
16463 pConfig->num_accept_mac = 0;
16464 pConfig->num_deny_mac = 0;
16465
16466 /**
16467 * access control policy
16468 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
16469 * listed in hostapd.deny file.
16470 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
16471 * listed in hostapd.accept file.
16472 */
16473 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
16474 {
16475 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
16476 }
16477 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
16478 {
16479 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
16480 }
16481 else
16482 {
16483 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16484 "%s:Acl Policy : %d is not supported",
16485 __func__, params->acl_policy);
16486 return -ENOTSUPP;
16487 }
16488
16489 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
16490 {
16491 pConfig->num_accept_mac = params->n_acl_entries;
16492 for (i = 0; i < params->n_acl_entries; i++)
16493 {
16494 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16495 "** Add ACL MAC entry %i in WhiletList :"
16496 MAC_ADDRESS_STR, i,
16497 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
16498
16499 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
16500 sizeof(qcmacaddr));
16501 }
16502 }
16503 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
16504 {
16505 pConfig->num_deny_mac = params->n_acl_entries;
16506 for (i = 0; i < params->n_acl_entries; i++)
16507 {
16508 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16509 "** Add ACL MAC entry %i in BlackList :"
16510 MAC_ADDRESS_STR, i,
16511 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
16512
16513 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
16514 sizeof(qcmacaddr));
16515 }
16516 }
16517
16518 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
16519 {
16520 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16521 "%s: SAP Set Mac Acl fail", __func__);
16522 return -EINVAL;
16523 }
16524 }
16525 else
16526 {
16527 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016528 "%s: Invalid device_mode = %s (%d)",
16529 __func__, hdd_device_modetoString(pAdapter->device_mode),
16530 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016531 return -EINVAL;
16532 }
16533
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016534 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016535 return 0;
16536}
16537
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016538static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
16539 struct net_device *dev,
16540 const struct cfg80211_acl_data *params)
16541{
16542 int ret;
16543 vos_ssr_protect(__func__);
16544 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
16545 vos_ssr_unprotect(__func__);
16546
16547 return ret;
16548}
16549
Leo Chang9056f462013-08-01 19:21:11 -070016550#ifdef WLAN_NL80211_TESTMODE
16551#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070016552void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070016553(
16554 void *pAdapter,
16555 void *indCont
16556)
16557{
Leo Changd9df8aa2013-09-26 13:32:26 -070016558 tSirLPHBInd *lphbInd;
16559 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053016560 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070016561
16562 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016563 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070016564
c_hpothu73f35e62014-04-18 13:40:08 +053016565 if (pAdapter == NULL)
16566 {
16567 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16568 "%s: pAdapter is NULL\n",__func__);
16569 return;
16570 }
16571
Leo Chang9056f462013-08-01 19:21:11 -070016572 if (NULL == indCont)
16573 {
16574 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016575 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070016576 return;
16577 }
16578
c_hpothu73f35e62014-04-18 13:40:08 +053016579 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070016580 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070016581 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053016582 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070016583 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070016584 GFP_ATOMIC);
16585 if (!skb)
16586 {
16587 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16588 "LPHB timeout, NL buffer alloc fail");
16589 return;
16590 }
16591
Leo Changac3ba772013-10-07 09:47:04 -070016592 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070016593 {
16594 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16595 "WLAN_HDD_TM_ATTR_CMD put fail");
16596 goto nla_put_failure;
16597 }
Leo Changac3ba772013-10-07 09:47:04 -070016598 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070016599 {
16600 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16601 "WLAN_HDD_TM_ATTR_TYPE put fail");
16602 goto nla_put_failure;
16603 }
Leo Changac3ba772013-10-07 09:47:04 -070016604 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070016605 sizeof(tSirLPHBInd), lphbInd))
16606 {
16607 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16608 "WLAN_HDD_TM_ATTR_DATA put fail");
16609 goto nla_put_failure;
16610 }
Leo Chang9056f462013-08-01 19:21:11 -070016611 cfg80211_testmode_event(skb, GFP_ATOMIC);
16612 return;
16613
16614nla_put_failure:
16615 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16616 "NLA Put fail");
16617 kfree_skb(skb);
16618
16619 return;
16620}
16621#endif /* FEATURE_WLAN_LPHB */
16622
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016623static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070016624{
16625 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
16626 int err = 0;
16627#ifdef FEATURE_WLAN_LPHB
16628 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070016629 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016630
16631 ENTER();
16632
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016633 err = wlan_hdd_validate_context(pHddCtx);
16634 if (0 != err)
16635 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016636 return err;
16637 }
Leo Chang9056f462013-08-01 19:21:11 -070016638#endif /* FEATURE_WLAN_LPHB */
16639
16640 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
16641 if (err)
16642 {
16643 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16644 "%s Testmode INV ATTR", __func__);
16645 return err;
16646 }
16647
16648 if (!tb[WLAN_HDD_TM_ATTR_CMD])
16649 {
16650 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16651 "%s Testmode INV CMD", __func__);
16652 return -EINVAL;
16653 }
16654
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016655 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16656 TRACE_CODE_HDD_CFG80211_TESTMODE,
16657 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070016658 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
16659 {
16660#ifdef FEATURE_WLAN_LPHB
16661 /* Low Power Heartbeat configuration request */
16662 case WLAN_HDD_TM_CMD_WLAN_HB:
16663 {
16664 int buf_len;
16665 void *buf;
16666 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080016667 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070016668
16669 if (!tb[WLAN_HDD_TM_ATTR_DATA])
16670 {
16671 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16672 "%s Testmode INV DATA", __func__);
16673 return -EINVAL;
16674 }
16675
16676 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
16677 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080016678
16679 hb_params_temp =(tSirLPHBReq *)buf;
16680 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
16681 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
16682 return -EINVAL;
16683
Leo Chang9056f462013-08-01 19:21:11 -070016684 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
16685 if (NULL == hb_params)
16686 {
16687 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16688 "%s Request Buffer Alloc Fail", __func__);
16689 return -EINVAL;
16690 }
16691
16692 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070016693 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
16694 hb_params,
16695 wlan_hdd_cfg80211_lphb_ind_handler);
16696 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070016697 {
Leo Changd9df8aa2013-09-26 13:32:26 -070016698 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16699 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070016700 vos_mem_free(hb_params);
16701 }
Leo Chang9056f462013-08-01 19:21:11 -070016702 return 0;
16703 }
16704#endif /* FEATURE_WLAN_LPHB */
16705 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016706 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16707 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070016708 return -EOPNOTSUPP;
16709 }
16710
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016711 EXIT();
16712 return err;
Leo Chang9056f462013-08-01 19:21:11 -070016713}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016714
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053016715static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
16716#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
16717 struct wireless_dev *wdev,
16718#endif
16719 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016720{
16721 int ret;
16722
16723 vos_ssr_protect(__func__);
16724 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
16725 vos_ssr_unprotect(__func__);
16726
16727 return ret;
16728}
Leo Chang9056f462013-08-01 19:21:11 -070016729#endif /* CONFIG_NL80211_TESTMODE */
16730
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016731static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016732 struct net_device *dev,
16733 int idx, struct survey_info *survey)
16734{
16735 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16736 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053016737 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016738 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053016739 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016740 v_S7_t snr,rssi;
16741 int status, i, j, filled = 0;
16742
16743 ENTER();
16744
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016745 if (NULL == pAdapter)
16746 {
16747 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16748 "%s: HDD adapter is Null", __func__);
16749 return -ENODEV;
16750 }
16751
16752 if (NULL == wiphy)
16753 {
16754 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16755 "%s: wiphy is Null", __func__);
16756 return -ENODEV;
16757 }
16758
16759 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16760 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016761 if (0 != status)
16762 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016763 return status;
16764 }
16765
Mihir Sheted9072e02013-08-21 17:02:29 +053016766 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16767
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016768 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053016769 0 != pAdapter->survey_idx ||
16770 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016771 {
16772 /* The survey dump ops when implemented completely is expected to
16773 * return a survey of all channels and the ops is called by the
16774 * kernel with incremental values of the argument 'idx' till it
16775 * returns -ENONET. But we can only support the survey for the
16776 * operating channel for now. survey_idx is used to track
16777 * that the ops is called only once and then return -ENONET for
16778 * the next iteration
16779 */
16780 pAdapter->survey_idx = 0;
16781 return -ENONET;
16782 }
16783
Mukul Sharma9d5233b2015-06-11 20:28:20 +053016784 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
16785 {
16786 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16787 "%s: Roaming in progress, hence return ", __func__);
16788 return -ENONET;
16789 }
16790
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016791 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16792
16793 wlan_hdd_get_snr(pAdapter, &snr);
16794 wlan_hdd_get_rssi(pAdapter, &rssi);
16795
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016796 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16797 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
16798 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016799 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
16800 hdd_wlan_get_freq(channel, &freq);
16801
16802
16803 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
16804 {
16805 if (NULL == wiphy->bands[i])
16806 {
16807 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
16808 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
16809 continue;
16810 }
16811
16812 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
16813 {
16814 struct ieee80211_supported_band *band = wiphy->bands[i];
16815
16816 if (band->channels[j].center_freq == (v_U16_t)freq)
16817 {
16818 survey->channel = &band->channels[j];
16819 /* The Rx BDs contain SNR values in dB for the received frames
16820 * while the supplicant expects noise. So we calculate and
16821 * return the value of noise (dBm)
16822 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
16823 */
16824 survey->noise = rssi - snr;
16825 survey->filled = SURVEY_INFO_NOISE_DBM;
16826 filled = 1;
16827 }
16828 }
16829 }
16830
16831 if (filled)
16832 pAdapter->survey_idx = 1;
16833 else
16834 {
16835 pAdapter->survey_idx = 0;
16836 return -ENONET;
16837 }
16838
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016839 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016840 return 0;
16841}
16842
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016843static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
16844 struct net_device *dev,
16845 int idx, struct survey_info *survey)
16846{
16847 int ret;
16848
16849 vos_ssr_protect(__func__);
16850 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
16851 vos_ssr_unprotect(__func__);
16852
16853 return ret;
16854}
16855
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016856/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016857 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016858 * this is called when cfg80211 driver resume
16859 * driver updates latest sched_scan scan result(if any) to cfg80211 database
16860 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016861int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016862{
16863 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16864 hdd_adapter_t *pAdapter;
16865 hdd_adapter_list_node_t *pAdapterNode, *pNext;
16866 VOS_STATUS status = VOS_STATUS_SUCCESS;
16867
16868 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016869
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016870 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016871 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016872 return 0;
16873 }
16874
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016875 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
16876 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016877 spin_lock(&pHddCtx->schedScan_lock);
16878 pHddCtx->isWiphySuspended = FALSE;
16879 if (TRUE != pHddCtx->isSchedScanUpdatePending)
16880 {
16881 spin_unlock(&pHddCtx->schedScan_lock);
16882 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16883 "%s: Return resume is not due to PNO indication", __func__);
16884 return 0;
16885 }
16886 // Reset flag to avoid updatating cfg80211 data old results again
16887 pHddCtx->isSchedScanUpdatePending = FALSE;
16888 spin_unlock(&pHddCtx->schedScan_lock);
16889
16890 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
16891
16892 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
16893 {
16894 pAdapter = pAdapterNode->pAdapter;
16895 if ( (NULL != pAdapter) &&
16896 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
16897 {
16898 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016899 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016900 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
16901 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016902 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016903 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016904 {
16905 /* Acquire wakelock to handle the case where APP's tries to
16906 * suspend immediately after updating the scan results. Whis
16907 * results in app's is in suspended state and not able to
16908 * process the connect request to AP
16909 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053016910 hdd_prevent_suspend_timeout(2000,
16911 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016912 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016913 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016914
16915 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16916 "%s : cfg80211 scan result database updated", __func__);
16917
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016918 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016919 return 0;
16920
16921 }
16922 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16923 pAdapterNode = pNext;
16924 }
16925
16926 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16927 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016928 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016929 return 0;
16930}
16931
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016932int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
16933{
16934 int ret;
16935
16936 vos_ssr_protect(__func__);
16937 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
16938 vos_ssr_unprotect(__func__);
16939
16940 return ret;
16941}
16942
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016943/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016944 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016945 * this is called when cfg80211 driver suspends
16946 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016947int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016948 struct cfg80211_wowlan *wow)
16949{
16950 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016951 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016952
16953 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016954
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016955 ret = wlan_hdd_validate_context(pHddCtx);
16956 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016957 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016958 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016959 }
16960
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016961
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016962 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16963 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
16964 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016965 pHddCtx->isWiphySuspended = TRUE;
16966
16967 EXIT();
16968
16969 return 0;
16970}
16971
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016972int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
16973 struct cfg80211_wowlan *wow)
16974{
16975 int ret;
16976
16977 vos_ssr_protect(__func__);
16978 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
16979 vos_ssr_unprotect(__func__);
16980
16981 return ret;
16982}
Jeff Johnson295189b2012-06-20 16:38:30 -070016983/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016984static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070016985{
16986 .add_virtual_intf = wlan_hdd_add_virtual_intf,
16987 .del_virtual_intf = wlan_hdd_del_virtual_intf,
16988 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
16989 .change_station = wlan_hdd_change_station,
16990#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
16991 .add_beacon = wlan_hdd_cfg80211_add_beacon,
16992 .del_beacon = wlan_hdd_cfg80211_del_beacon,
16993 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016994#else
16995 .start_ap = wlan_hdd_cfg80211_start_ap,
16996 .change_beacon = wlan_hdd_cfg80211_change_beacon,
16997 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070016998#endif
16999 .change_bss = wlan_hdd_cfg80211_change_bss,
17000 .add_key = wlan_hdd_cfg80211_add_key,
17001 .get_key = wlan_hdd_cfg80211_get_key,
17002 .del_key = wlan_hdd_cfg80211_del_key,
17003 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080017004#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070017005 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080017006#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017007 .scan = wlan_hdd_cfg80211_scan,
17008 .connect = wlan_hdd_cfg80211_connect,
17009 .disconnect = wlan_hdd_cfg80211_disconnect,
17010 .join_ibss = wlan_hdd_cfg80211_join_ibss,
17011 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
17012 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
17013 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
17014 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070017015 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
17016 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053017017 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070017018#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
17019 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
17020 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
17021 .set_txq_params = wlan_hdd_set_txq_params,
17022#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070017023 .get_station = wlan_hdd_cfg80211_get_station,
17024 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
17025 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070017026 .add_station = wlan_hdd_cfg80211_add_station,
17027#ifdef FEATURE_WLAN_LFR
17028 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
17029 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
17030 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
17031#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070017032#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
17033 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
17034#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080017035#ifdef FEATURE_WLAN_TDLS
17036 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
17037 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
17038#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053017039#ifdef WLAN_FEATURE_GTK_OFFLOAD
17040 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
17041#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053017042#ifdef FEATURE_WLAN_SCAN_PNO
17043 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
17044 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
17045#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053017046 .resume = wlan_hdd_cfg80211_resume_wlan,
17047 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053017048 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070017049#ifdef WLAN_NL80211_TESTMODE
17050 .testmode_cmd = wlan_hdd_cfg80211_testmode,
17051#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053017052 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070017053};
17054