blob: 28d472dfd39a723cdf679cb4d645d35f70cb818a [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,
1077 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1078 pWifiIfaceStat->beaconRx) ||
1079 nla_put_u32(vendor_event,
1080 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1081 pWifiIfaceStat->mgmtRx) ||
1082 nla_put_u32(vendor_event,
1083 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1084 pWifiIfaceStat->mgmtActionRx) ||
1085 nla_put_u32(vendor_event,
1086 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1087 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301088 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301089 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1090 pWifiIfaceStat->rssiMgmt) ||
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_DATA,
1093 pWifiIfaceStat->rssiData) ||
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_ACK,
1096 pWifiIfaceStat->rssiAck))
1097 {
1098 hddLog(VOS_TRACE_LEVEL_ERROR,
1099 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301100 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301101 return FALSE;
1102 }
1103
1104 wmmInfo = nla_nest_start(vendor_event,
1105 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301106 if(!wmmInfo)
1107 {
1108 vos_mem_free(pWifiIfaceStatTL);
1109 return FALSE;
1110 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301111 for (i = 0; i < WIFI_AC_MAX; i++)
1112 {
1113 struct nlattr *wmmStats;
1114 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301115 if(!wmmStats)
1116 {
1117 vos_mem_free(pWifiIfaceStatTL);
1118 return FALSE;
1119 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301120 if (FALSE == put_wifi_wmm_ac_stat(
1121 &pWifiIfaceStat->AccessclassStats[i],
1122 vendor_event))
1123 {
1124 hddLog(VOS_TRACE_LEVEL_ERROR,
1125 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301126 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301127 return FALSE;
1128 }
1129
1130 nla_nest_end(vendor_event, wmmStats);
1131 }
1132 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301133 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301134 return TRUE;
1135}
1136
1137static tSirWifiInterfaceMode
1138 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1139{
1140 switch (deviceMode)
1141 {
1142 case WLAN_HDD_INFRA_STATION:
1143 return WIFI_INTERFACE_STA;
1144 case WLAN_HDD_SOFTAP:
1145 return WIFI_INTERFACE_SOFTAP;
1146 case WLAN_HDD_P2P_CLIENT:
1147 return WIFI_INTERFACE_P2P_CLIENT;
1148 case WLAN_HDD_P2P_GO:
1149 return WIFI_INTERFACE_P2P_GO;
1150 case WLAN_HDD_IBSS:
1151 return WIFI_INTERFACE_IBSS;
1152 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301153 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301154 }
1155}
1156
1157static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1158 tpSirWifiInterfaceInfo pInfo)
1159{
1160 v_U8_t *staMac = NULL;
1161 hdd_station_ctx_t *pHddStaCtx;
1162 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1163 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1164
1165 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1166
1167 vos_mem_copy(pInfo->macAddr,
1168 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1169
1170 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1171 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1172 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1173 {
1174 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1175 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1176 {
1177 pInfo->state = WIFI_DISCONNECTED;
1178 }
1179 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1180 {
1181 hddLog(VOS_TRACE_LEVEL_ERROR,
1182 "%s: Session ID %d, Connection is in progress", __func__,
1183 pAdapter->sessionId);
1184 pInfo->state = WIFI_ASSOCIATING;
1185 }
1186 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1187 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1188 {
1189 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1190 hddLog(VOS_TRACE_LEVEL_ERROR,
1191 "%s: client " MAC_ADDRESS_STR
1192 " is in the middle of WPS/EAPOL exchange.", __func__,
1193 MAC_ADDR_ARRAY(staMac));
1194 pInfo->state = WIFI_AUTHENTICATING;
1195 }
1196 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1197 {
1198 pInfo->state = WIFI_ASSOCIATED;
1199 vos_mem_copy(pInfo->bssid,
1200 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1201 vos_mem_copy(pInfo->ssid,
1202 pHddStaCtx->conn_info.SSID.SSID.ssId,
1203 pHddStaCtx->conn_info.SSID.SSID.length);
1204 //NULL Terminate the string.
1205 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1206 }
1207 }
1208 vos_mem_copy(pInfo->countryStr,
1209 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1210
1211 vos_mem_copy(pInfo->apCountryStr,
1212 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1213
1214 return TRUE;
1215}
1216
1217/*
1218 * hdd_link_layer_process_peer_stats () - This function is called after
1219 * receiving Link Layer Peer statistics from FW.This function converts
1220 * the firmware data to the NL data and sends the same to the kernel/upper
1221 * layers.
1222 */
1223static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1224 v_VOID_t *pData)
1225{
1226 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1227 tpSirWifiRateStat pWifiRateStat;
1228 tpSirWifiPeerStat pWifiPeerStat;
1229 tpSirWifiPeerInfo pWifiPeerInfo;
1230 struct nlattr *peerInfo;
1231 struct sk_buff *vendor_event;
1232 int status, i;
1233
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301234 ENTER();
1235
Sunil Duttc69bccb2014-05-26 21:30:20 +05301236 status = wlan_hdd_validate_context(pHddCtx);
1237 if (0 != status)
1238 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301239 return;
1240 }
1241
1242 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1243
1244 hddLog(VOS_TRACE_LEVEL_INFO,
1245 "LL_STATS_PEER_ALL : numPeers %u",
1246 pWifiPeerStat->numPeers);
1247 {
1248 for (i = 0; i < pWifiPeerStat->numPeers; i++)
1249 {
1250 pWifiPeerInfo = (tpSirWifiPeerInfo)
1251 ((uint8 *)pWifiPeerStat->peerInfo +
1252 ( i * sizeof(tSirWifiPeerInfo)));
1253
Dasari Srinivas1be0c4e2014-10-19 13:03:41 +05301254 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) {
1255 pWifiPeerInfo->type = WIFI_PEER_AP;
1256 }
1257 if (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) {
1258 pWifiPeerInfo->type = WIFI_PEER_P2P_GO;
1259 }
1260
Sunil Duttc69bccb2014-05-26 21:30:20 +05301261 hddLog(VOS_TRACE_LEVEL_INFO,
1262 " %d) LL_STATS Channel Stats "
1263 " Peer Type %u "
1264 " peerMacAddress %pM "
1265 " capabilities 0x%x "
1266 " numRate %u ",
1267 i,
1268 pWifiPeerInfo->type,
1269 pWifiPeerInfo->peerMacAddress,
1270 pWifiPeerInfo->capabilities,
1271 pWifiPeerInfo->numRate);
1272 {
1273 int j;
1274 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1275 {
1276 pWifiRateStat = (tpSirWifiRateStat)
1277 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1278 ( j * sizeof(tSirWifiRateStat)));
1279
1280 hddLog(VOS_TRACE_LEVEL_INFO,
1281 " peer Rate Stats "
1282 " preamble %u "
1283 " nss %u "
1284 " bw %u "
1285 " rateMcsIdx %u "
1286 " reserved %u "
1287 " bitrate %u "
1288 " txMpdu %u "
1289 " rxMpdu %u "
1290 " mpduLost %u "
1291 " retries %u "
1292 " retriesShort %u "
1293 " retriesLong %u",
1294 pWifiRateStat->rate.preamble,
1295 pWifiRateStat->rate.nss,
1296 pWifiRateStat->rate.bw,
1297 pWifiRateStat->rate.rateMcsIdx,
1298 pWifiRateStat->rate.reserved,
1299 pWifiRateStat->rate.bitrate,
1300 pWifiRateStat->txMpdu,
1301 pWifiRateStat->rxMpdu,
1302 pWifiRateStat->mpduLost,
1303 pWifiRateStat->retries,
1304 pWifiRateStat->retriesShort,
1305 pWifiRateStat->retriesLong);
1306 }
1307 }
1308 }
1309 }
1310
1311 /*
1312 * Allocate a size of 4096 for the peer stats comprising
1313 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1314 * sizeof (tSirWifiRateStat).Each field is put with an
1315 * NL attribute.The size of 4096 is considered assuming
1316 * that number of rates shall not exceed beyond 50 with
1317 * the sizeof (tSirWifiRateStat) being 32.
1318 */
1319 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05301320#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
1321 NULL,
1322#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301323 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1324 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1325 GFP_KERNEL);
1326 if (!vendor_event)
1327 {
1328 hddLog(VOS_TRACE_LEVEL_ERROR,
1329 "%s: cfg80211_vendor_event_alloc failed",
1330 __func__);
1331 return;
1332 }
1333 if (nla_put_u32(vendor_event,
1334 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1335 pWifiPeerStat->numPeers))
1336 {
1337 hddLog(VOS_TRACE_LEVEL_ERROR,
1338 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1339 kfree_skb(vendor_event);
1340 return;
1341 }
1342
1343 peerInfo = nla_nest_start(vendor_event,
1344 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301345 if(!peerInfo)
1346 {
1347 hddLog(VOS_TRACE_LEVEL_ERROR,
1348 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1349 __func__);
1350 kfree_skb(vendor_event);
1351 return;
1352 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301353
1354 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1355 pWifiPeerStat->peerInfo);
1356
1357 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1358 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301359 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301360 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301361
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301362 if(!peers)
1363 {
1364 hddLog(VOS_TRACE_LEVEL_ERROR,
1365 "%s: peer stats put fail",
1366 __func__);
1367 kfree_skb(vendor_event);
1368 return;
1369 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301370 if (FALSE == put_wifi_peer_info(
1371 pWifiPeerInfo, vendor_event))
1372 {
1373 hddLog(VOS_TRACE_LEVEL_ERROR,
1374 "%s: put_wifi_peer_info put fail", __func__);
1375 kfree_skb(vendor_event);
1376 return;
1377 }
1378
1379 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1380 pWifiPeerStat->peerInfo +
1381 (i * sizeof(tSirWifiPeerInfo)) +
1382 (numRate * sizeof (tSirWifiRateStat)));
1383 nla_nest_end(vendor_event, peers);
1384 }
1385 nla_nest_end(vendor_event, peerInfo);
1386 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301387
1388 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 */
1419 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05301420#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
1421 NULL,
1422#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301423 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1424 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1425 GFP_KERNEL);
1426 if (!vendor_event)
1427 {
1428 hddLog(VOS_TRACE_LEVEL_ERROR,
1429 FL("cfg80211_vendor_event_alloc failed") );
1430 return;
1431 }
1432
1433 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1434
Dino Mycle3b9536d2014-07-09 22:05:24 +05301435
1436 if (FALSE == hdd_get_interface_info( pAdapter,
1437 &pWifiIfaceStat->info))
1438 {
1439 hddLog(VOS_TRACE_LEVEL_ERROR,
1440 FL("hdd_get_interface_info get fail") );
1441 kfree_skb(vendor_event);
1442 return;
1443 }
1444
1445 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1446 vendor_event))
1447 {
1448 hddLog(VOS_TRACE_LEVEL_ERROR,
1449 FL("put_wifi_iface_stats fail") );
1450 kfree_skb(vendor_event);
1451 return;
1452 }
1453
Sunil Duttc69bccb2014-05-26 21:30:20 +05301454 hddLog(VOS_TRACE_LEVEL_INFO,
1455 "WMI_LINK_STATS_IFACE Data");
1456
1457 hddLog(VOS_TRACE_LEVEL_INFO,
1458 "LL_STATS_IFACE: "
1459 " Mode %u "
1460 " MAC %pM "
1461 " State %u "
1462 " Roaming %u "
1463 " capabilities 0x%x "
1464 " SSID %s "
1465 " BSSID %pM",
1466 pWifiIfaceStat->info.mode,
1467 pWifiIfaceStat->info.macAddr,
1468 pWifiIfaceStat->info.state,
1469 pWifiIfaceStat->info.roaming,
1470 pWifiIfaceStat->info.capabilities,
1471 pWifiIfaceStat->info.ssid,
1472 pWifiIfaceStat->info.bssid);
1473
1474 hddLog(VOS_TRACE_LEVEL_INFO,
1475 " AP country str: %c%c%c",
1476 pWifiIfaceStat->info.apCountryStr[0],
1477 pWifiIfaceStat->info.apCountryStr[1],
1478 pWifiIfaceStat->info.apCountryStr[2]);
1479
1480
1481 hddLog(VOS_TRACE_LEVEL_INFO,
1482 " Country Str Association: %c%c%c",
1483 pWifiIfaceStat->info.countryStr[0],
1484 pWifiIfaceStat->info.countryStr[1],
1485 pWifiIfaceStat->info.countryStr[2]);
1486
1487 hddLog(VOS_TRACE_LEVEL_INFO,
1488 " beaconRx %u "
1489 " mgmtRx %u "
1490 " mgmtActionRx %u "
1491 " mgmtActionTx %u "
Dino Mycle3b9536d2014-07-09 22:05:24 +05301492 " rssiMgmt %d "
1493 " rssiData %d "
1494 " rssiAck %d",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301495 pWifiIfaceStat->beaconRx,
1496 pWifiIfaceStat->mgmtRx,
1497 pWifiIfaceStat->mgmtActionRx,
1498 pWifiIfaceStat->mgmtActionTx,
1499 pWifiIfaceStat->rssiMgmt,
1500 pWifiIfaceStat->rssiData,
1501 pWifiIfaceStat->rssiAck );
1502
1503
1504 {
1505 int i;
1506 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1507 {
1508 hddLog(VOS_TRACE_LEVEL_INFO,
1509
1510 " %d) LL_STATS IFACE: "
1511 " ac: %u txMpdu: %u "
1512 " rxMpdu: %u txMcast: %u "
1513 " rxMcast: %u rxAmpdu: %u "
1514 " txAmpdu: %u mpduLost: %u "
1515 " retries: %u retriesShort: %u "
1516 " retriesLong: %u contentionTimeMin: %u "
1517 " contentionTimeMax: %u contentionTimeAvg: %u "
1518 " contentionNumSamples: %u",
1519 i,
1520 pWifiIfaceStat->AccessclassStats[i].ac,
1521 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1522 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1523 pWifiIfaceStat->AccessclassStats[i].txMcast,
1524 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1525 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1526 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1527 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1528 pWifiIfaceStat->AccessclassStats[i].retries,
1529 pWifiIfaceStat->
1530 AccessclassStats[i].retriesShort,
1531 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1532 pWifiIfaceStat->
1533 AccessclassStats[i].contentionTimeMin,
1534 pWifiIfaceStat->
1535 AccessclassStats[i].contentionTimeMax,
1536 pWifiIfaceStat->
1537 AccessclassStats[i].contentionTimeAvg,
1538 pWifiIfaceStat->
1539 AccessclassStats[i].contentionNumSamples);
1540
1541 }
1542 }
1543
Sunil Duttc69bccb2014-05-26 21:30:20 +05301544 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301545
1546 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301547}
1548
1549/*
1550 * hdd_link_layer_process_radio_stats () - This function is called after
1551 * receiving Link Layer Radio statistics from FW.This function converts
1552 * the firmware data to the NL data and sends the same to the kernel/upper
1553 * layers.
1554 */
1555static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1556 v_VOID_t *pData)
1557{
1558 int status, i;
1559 tpSirWifiRadioStat pWifiRadioStat;
1560 tpSirWifiChannelStats pWifiChannelStats;
1561 struct sk_buff *vendor_event;
1562 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1563 struct nlattr *chList;
1564
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301565 ENTER();
1566
Sunil Duttc69bccb2014-05-26 21:30:20 +05301567 status = wlan_hdd_validate_context(pHddCtx);
1568 if (0 != status)
1569 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301570 return;
1571 }
1572 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1573
1574 hddLog(VOS_TRACE_LEVEL_INFO,
1575 "LL_STATS_RADIO"
1576 " radio is %d onTime is %u "
1577 " txTime is %u rxTime is %u "
1578 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301579 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301580 " onTimePnoScan is %u onTimeHs20 is %u "
1581 " numChannels is %u",
1582 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1583 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1584 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301585 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301586 pWifiRadioStat->onTimeRoamScan,
1587 pWifiRadioStat->onTimePnoScan,
1588 pWifiRadioStat->onTimeHs20,
1589 pWifiRadioStat->numChannels);
1590 /*
1591 * Allocate a size of 4096 for the Radio stats comprising
1592 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1593 * (tSirWifiChannelStats).Each channel data is put with an
1594 * NL attribute.The size of 4096 is considered assuming that
1595 * number of channels shall not exceed beyond 60 with the
1596 * sizeof (tSirWifiChannelStats) being 24 bytes.
1597 */
1598
1599 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05301600#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
1601 NULL,
1602#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301603 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1604 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1605 GFP_KERNEL);
1606
1607 if (!vendor_event)
1608 {
1609 hddLog(VOS_TRACE_LEVEL_ERROR,
1610 FL("cfg80211_vendor_event_alloc failed") );
1611 return;
1612 }
1613
1614 if (nla_put_u32(vendor_event,
1615 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1616 pWifiRadioStat->radio) ||
1617 nla_put_u32(vendor_event,
1618 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1619 pWifiRadioStat->onTime) ||
1620 nla_put_u32(vendor_event,
1621 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1622 pWifiRadioStat->txTime) ||
1623 nla_put_u32(vendor_event,
1624 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1625 pWifiRadioStat->rxTime) ||
1626 nla_put_u32(vendor_event,
1627 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1628 pWifiRadioStat->onTimeScan) ||
1629 nla_put_u32(vendor_event,
1630 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1631 pWifiRadioStat->onTimeNbd) ||
1632 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301633 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1634 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301635 nla_put_u32(vendor_event,
1636 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1637 pWifiRadioStat->onTimeRoamScan) ||
1638 nla_put_u32(vendor_event,
1639 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1640 pWifiRadioStat->onTimePnoScan) ||
1641 nla_put_u32(vendor_event,
1642 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1643 pWifiRadioStat->onTimeHs20) ||
1644 nla_put_u32(vendor_event,
1645 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1646 pWifiRadioStat->numChannels))
1647 {
1648 hddLog(VOS_TRACE_LEVEL_ERROR,
1649 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1650 kfree_skb(vendor_event);
1651 return ;
1652 }
1653
1654 chList = nla_nest_start(vendor_event,
1655 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301656 if(!chList)
1657 {
1658 hddLog(VOS_TRACE_LEVEL_ERROR,
1659 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1660 __func__);
1661 kfree_skb(vendor_event);
1662 return;
1663 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301664 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1665 {
1666 struct nlattr *chInfo;
1667
1668 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1669 pWifiRadioStat->channels +
1670 (i * sizeof(tSirWifiChannelStats)));
1671
1672 hddLog(VOS_TRACE_LEVEL_INFO,
1673 " %d) Channel Info"
1674 " width is %u "
1675 " CenterFreq %u "
1676 " CenterFreq0 %u "
1677 " CenterFreq1 %u "
1678 " onTime %u "
1679 " ccaBusyTime %u",
1680 i,
1681 pWifiChannelStats->channel.width,
1682 pWifiChannelStats->channel.centerFreq,
1683 pWifiChannelStats->channel.centerFreq0,
1684 pWifiChannelStats->channel.centerFreq1,
1685 pWifiChannelStats->onTime,
1686 pWifiChannelStats->ccaBusyTime);
1687
1688
1689 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301690 if(!chInfo)
1691 {
1692 hddLog(VOS_TRACE_LEVEL_ERROR,
1693 "%s: failed to put chInfo",
1694 __func__);
1695 kfree_skb(vendor_event);
1696 return;
1697 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301698
1699 if (nla_put_u32(vendor_event,
1700 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1701 pWifiChannelStats->channel.width) ||
1702 nla_put_u32(vendor_event,
1703 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1704 pWifiChannelStats->channel.centerFreq) ||
1705 nla_put_u32(vendor_event,
1706 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1707 pWifiChannelStats->channel.centerFreq0) ||
1708 nla_put_u32(vendor_event,
1709 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1710 pWifiChannelStats->channel.centerFreq1) ||
1711 nla_put_u32(vendor_event,
1712 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1713 pWifiChannelStats->onTime) ||
1714 nla_put_u32(vendor_event,
1715 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1716 pWifiChannelStats->ccaBusyTime))
1717 {
1718 hddLog(VOS_TRACE_LEVEL_ERROR,
1719 FL("cfg80211_vendor_event_alloc failed") );
1720 kfree_skb(vendor_event);
1721 return ;
1722 }
1723 nla_nest_end(vendor_event, chInfo);
1724 }
1725 nla_nest_end(vendor_event, chList);
1726
1727 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301728
1729 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301730 return;
1731}
1732
1733/*
1734 * hdd_link_layer_stats_ind_callback () - This function is called after
1735 * receiving Link Layer indications from FW.This callback converts the firmware
1736 * data to the NL data and send the same to the kernel/upper layers.
1737 */
1738static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1739 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301740 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301741{
Dino Mycled3d50022014-07-07 12:58:25 +05301742 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1743 hdd_adapter_t *pAdapter = NULL;
1744 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301745 int status;
1746
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301747 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301748
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301749 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301750 if (0 != status)
1751 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301752 return;
1753 }
1754
Dino Mycled3d50022014-07-07 12:58:25 +05301755 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1756 if (NULL == pAdapter)
1757 {
1758 hddLog(VOS_TRACE_LEVEL_ERROR,
1759 FL(" MAC address %pM does not exist with host"),
1760 macAddr);
1761 return;
1762 }
1763
Sunil Duttc69bccb2014-05-26 21:30:20 +05301764 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301765 "%s: Interface: %s LLStats indType: %d", __func__,
1766 pAdapter->dev->name, indType);
1767
Sunil Duttc69bccb2014-05-26 21:30:20 +05301768 switch (indType)
1769 {
1770 case SIR_HAL_LL_STATS_RESULTS_RSP:
1771 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301772 hddLog(VOS_TRACE_LEVEL_INFO,
1773 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1774 hddLog(VOS_TRACE_LEVEL_INFO,
1775 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1776 linkLayerStatsResults->paramId);
1777 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301778 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1779 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301780 hddLog(VOS_TRACE_LEVEL_INFO,
1781 "LL_STATS RESULTS RESPONSE respId = %u",
1782 linkLayerStatsResults->respId);
1783 hddLog(VOS_TRACE_LEVEL_INFO,
1784 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1785 linkLayerStatsResults->moreResultToFollow);
1786 hddLog(VOS_TRACE_LEVEL_INFO,
1787 "LL_STATS RESULTS RESPONSE result = %p",
1788 linkLayerStatsResults->result);
1789 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1790 {
1791 hdd_link_layer_process_radio_stats(pAdapter,
1792 (v_VOID_t *)linkLayerStatsResults->result);
1793 }
1794 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1795 {
1796 hdd_link_layer_process_iface_stats(pAdapter,
1797 (v_VOID_t *)linkLayerStatsResults->result);
1798 }
1799 else if ( linkLayerStatsResults->paramId &
1800 WMI_LINK_STATS_ALL_PEER )
1801 {
1802 hdd_link_layer_process_peer_stats(pAdapter,
1803 (v_VOID_t *)linkLayerStatsResults->result);
1804 } /* WMI_LINK_STATS_ALL_PEER */
1805 else
1806 {
1807 hddLog(VOS_TRACE_LEVEL_ERROR,
1808 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1809 }
1810
1811 break;
1812 }
1813 default:
1814 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1815 break;
1816 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301817
1818 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301819 return;
1820}
1821
1822const struct
1823nla_policy
1824qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1825{
1826 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1827 { .type = NLA_U32 },
1828 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1829 { .type = NLA_U32 },
1830};
1831
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301832static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1833 struct wireless_dev *wdev,
1834 const void *data,
1835 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301836{
1837 int status;
1838 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301839 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301840 struct net_device *dev = wdev->netdev;
1841 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1842 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Srinivas Dasari98947432014-11-07 19:41:24 +05301843 hdd_station_ctx_t *pHddStaCtx;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301844
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301845 ENTER();
1846
Sunil Duttc69bccb2014-05-26 21:30:20 +05301847 status = wlan_hdd_validate_context(pHddCtx);
1848 if (0 != status)
1849 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301850 return -EINVAL;
1851 }
1852
1853 if (NULL == pAdapter)
1854 {
1855 hddLog(VOS_TRACE_LEVEL_ERROR,
1856 FL("HDD adapter is Null"));
1857 return -ENODEV;
1858 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301859 /* check the LLStats Capability */
1860 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1861 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1862 {
1863 hddLog(VOS_TRACE_LEVEL_ERROR,
1864 FL("Link Layer Statistics not supported by Firmware"));
1865 return -EINVAL;
1866 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301867
1868 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1869 (struct nlattr *)data,
1870 data_len, qca_wlan_vendor_ll_set_policy))
1871 {
1872 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1873 return -EINVAL;
1874 }
1875 if (!tb_vendor
1876 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1877 {
1878 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1879 return -EINVAL;
1880 }
1881 if (!tb_vendor[
1882 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1883 {
1884 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1885 return -EINVAL;
1886 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301887 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301888 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301889
Dino Mycledf0a5d92014-07-04 09:41:55 +05301890 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301891 nla_get_u32(
1892 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1893
Dino Mycledf0a5d92014-07-04 09:41:55 +05301894 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301895 nla_get_u32(
1896 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1897
Dino Mycled3d50022014-07-07 12:58:25 +05301898 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1899 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301900
1901
1902 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301903 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301904 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301905 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301906 hddLog(VOS_TRACE_LEVEL_INFO,
1907 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301908 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301909 hddLog(VOS_TRACE_LEVEL_INFO,
1910 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301911 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301912
1913 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1914 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301915 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301916 {
1917 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1918 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301919 return -EINVAL;
1920
1921 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301922
1923 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1924 if (VOS_STATUS_SUCCESS !=
1925 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1926 pHddStaCtx->conn_info.staId[0], WIFI_STATS_IFACE))
1927 {
1928 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1929 "WLANTL_ClearInterfaceStats Failed", __func__);
1930 return -EINVAL;
1931 }
1932
Sunil Duttc69bccb2014-05-26 21:30:20 +05301933 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301934 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301935 {
1936 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1937 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301938 return -EINVAL;
1939 }
1940
1941 pAdapter->isLinkLayerStatsSet = 1;
1942
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301943 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301944 return 0;
1945}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301946static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1947 struct wireless_dev *wdev,
1948 const void *data,
1949 int data_len)
1950{
1951 int ret = 0;
1952
1953 vos_ssr_protect(__func__);
1954 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1955 vos_ssr_unprotect(__func__);
1956
1957 return ret;
1958}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301959
1960const struct
1961nla_policy
1962qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1963{
1964 /* Unsigned 32bit value provided by the caller issuing the GET stats
1965 * command. When reporting
1966 * the stats results, the driver uses the same value to indicate
1967 * which GET request the results
1968 * correspond to.
1969 */
1970 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1971
1972 /* Unsigned 32bit value . bit mask to identify what statistics are
1973 requested for retrieval */
1974 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1975};
1976
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301977static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1978 struct wireless_dev *wdev,
1979 const void *data,
1980 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301981{
1982 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1983 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301984 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301985 struct net_device *dev = wdev->netdev;
1986 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301987 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301988 int status;
1989
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301990 ENTER();
1991
Sunil Duttc69bccb2014-05-26 21:30:20 +05301992 status = wlan_hdd_validate_context(pHddCtx);
1993 if (0 != status)
1994 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301995 return -EINVAL ;
1996 }
1997
1998 if (NULL == pAdapter)
1999 {
2000 hddLog(VOS_TRACE_LEVEL_FATAL,
2001 "%s: HDD adapter is Null", __func__);
2002 return -ENODEV;
2003 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302004
2005 if (pHddStaCtx == NULL)
2006 {
2007 hddLog(VOS_TRACE_LEVEL_FATAL,
2008 "%s: HddStaCtx is Null", __func__);
2009 return -ENODEV;
2010 }
2011
Dino Mycledf0a5d92014-07-04 09:41:55 +05302012 /* check the LLStats Capability */
2013 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2014 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2015 {
2016 hddLog(VOS_TRACE_LEVEL_ERROR,
2017 FL("Link Layer Statistics not supported by Firmware"));
2018 return -EINVAL;
2019 }
2020
Sunil Duttc69bccb2014-05-26 21:30:20 +05302021
2022 if (!pAdapter->isLinkLayerStatsSet)
2023 {
2024 hddLog(VOS_TRACE_LEVEL_FATAL,
2025 "%s: isLinkLayerStatsSet : %d",
2026 __func__, pAdapter->isLinkLayerStatsSet);
2027 return -EINVAL;
2028 }
2029
Mukul Sharma10313ba2015-07-29 19:14:39 +05302030 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2031 {
2032 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2033 "%s: Roaming in progress, so unable to proceed this request", __func__);
2034 return -EBUSY;
2035 }
2036
Sunil Duttc69bccb2014-05-26 21:30:20 +05302037 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2038 (struct nlattr *)data,
2039 data_len, qca_wlan_vendor_ll_get_policy))
2040 {
2041 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2042 return -EINVAL;
2043 }
2044
2045 if (!tb_vendor
2046 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2047 {
2048 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2049 return -EINVAL;
2050 }
2051
2052 if (!tb_vendor
2053 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2054 {
2055 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2056 return -EINVAL;
2057 }
2058
Sunil Duttc69bccb2014-05-26 21:30:20 +05302059
Dino Mycledf0a5d92014-07-04 09:41:55 +05302060 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302061 nla_get_u32( tb_vendor[
2062 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302063 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302064 nla_get_u32( tb_vendor[
2065 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2066
Dino Mycled3d50022014-07-07 12:58:25 +05302067 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2068 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302069
2070 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302071 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302072 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302073 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302074 hddLog(VOS_TRACE_LEVEL_INFO,
2075 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302076 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302077
2078 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302079 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302080 {
2081 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2082 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302083 return -EINVAL;
2084 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302085
2086 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302087 return 0;
2088}
2089
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302090static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2091 struct wireless_dev *wdev,
2092 const void *data,
2093 int data_len)
2094{
2095 int ret = 0;
2096
2097 vos_ssr_protect(__func__);
2098 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
2099 vos_ssr_unprotect(__func__);
2100
2101 return ret;
2102}
2103
Sunil Duttc69bccb2014-05-26 21:30:20 +05302104const struct
2105nla_policy
2106qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
2107{
2108 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
2109 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
2110 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
2111 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
2112};
2113
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302114static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2115 struct wireless_dev *wdev,
2116 const void *data,
2117 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302118{
2119 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2120 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302121 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302122 struct net_device *dev = wdev->netdev;
2123 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2124 u32 statsClearReqMask;
2125 u8 stopReq;
2126 int status;
2127
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302128 ENTER();
2129
Sunil Duttc69bccb2014-05-26 21:30:20 +05302130 status = wlan_hdd_validate_context(pHddCtx);
2131 if (0 != status)
2132 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302133 return -EINVAL;
2134 }
2135
2136 if (NULL == pAdapter)
2137 {
2138 hddLog(VOS_TRACE_LEVEL_FATAL,
2139 "%s: HDD adapter is Null", __func__);
2140 return -ENODEV;
2141 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302142 /* check the LLStats Capability */
2143 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2144 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2145 {
2146 hddLog(VOS_TRACE_LEVEL_ERROR,
2147 FL("Enable LLStats Capability"));
2148 return -EINVAL;
2149 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302150
2151 if (!pAdapter->isLinkLayerStatsSet)
2152 {
2153 hddLog(VOS_TRACE_LEVEL_FATAL,
2154 "%s: isLinkLayerStatsSet : %d",
2155 __func__, pAdapter->isLinkLayerStatsSet);
2156 return -EINVAL;
2157 }
2158
2159 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2160 (struct nlattr *)data,
2161 data_len, qca_wlan_vendor_ll_clr_policy))
2162 {
2163 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2164 return -EINVAL;
2165 }
2166
2167 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2168
2169 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2170 {
2171 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2172 return -EINVAL;
2173
2174 }
2175
Sunil Duttc69bccb2014-05-26 21:30:20 +05302176
Dino Mycledf0a5d92014-07-04 09:41:55 +05302177 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302178 nla_get_u32(
2179 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2180
Dino Mycledf0a5d92014-07-04 09:41:55 +05302181 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302182 nla_get_u8(
2183 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2184
2185 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302186 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302187
Dino Mycled3d50022014-07-07 12:58:25 +05302188 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2189 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302190
2191 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302192 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302193 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302194 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302195 hddLog(VOS_TRACE_LEVEL_INFO,
2196 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302197 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302198 hddLog(VOS_TRACE_LEVEL_INFO,
2199 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302200 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302201
2202 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302203 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302204 {
2205 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302206 hdd_station_ctx_t *pHddStaCtx;
2207
2208 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2209 if (VOS_STATUS_SUCCESS !=
2210 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2211 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2212 {
2213 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2214 "WLANTL_ClearInterfaceStats Failed", __func__);
2215 return -EINVAL;
2216 }
2217 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2218 (statsClearReqMask & WIFI_STATS_IFACE)) {
2219 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2220 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2221 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2222 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2223 }
2224
Sunil Duttc69bccb2014-05-26 21:30:20 +05302225 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2226 2 * sizeof(u32) +
2227 NLMSG_HDRLEN);
2228
2229 if (temp_skbuff != NULL)
2230 {
2231
2232 if (nla_put_u32(temp_skbuff,
2233 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2234 statsClearReqMask) ||
2235 nla_put_u32(temp_skbuff,
2236 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2237 stopReq))
2238 {
2239 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2240 kfree_skb(temp_skbuff);
2241 return -EINVAL;
2242 }
2243 /* If the ask is to stop the stats collection as part of clear
2244 * (stopReq = 1) , ensure that no further requests of get
2245 * go to the firmware by having isLinkLayerStatsSet set to 0.
2246 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302247 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302248 * case the firmware is just asked to clear the statistics.
2249 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302250 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302251 pAdapter->isLinkLayerStatsSet = 0;
2252 return cfg80211_vendor_cmd_reply(temp_skbuff);
2253 }
2254 return -ENOMEM;
2255 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302256
2257 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302258 return -EINVAL;
2259}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302260static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2261 struct wireless_dev *wdev,
2262 const void *data,
2263 int data_len)
2264{
2265 int ret = 0;
2266
2267 vos_ssr_protect(__func__);
2268 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2269 vos_ssr_unprotect(__func__);
2270
2271 return ret;
2272
2273
2274}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302275#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2276
Dino Mycle6fb96c12014-06-10 11:52:40 +05302277#ifdef WLAN_FEATURE_EXTSCAN
2278static const struct nla_policy
2279wlan_hdd_extscan_config_policy
2280 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2281{
2282 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2283 { .type = NLA_U32 },
2284 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2285 { .type = NLA_U32 },
2286 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2287 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2288 { .type = NLA_U32 },
2289 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2290 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2291
2292 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2293 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2294 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2295 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2296 { .type = NLA_U8 },
2297 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2298 { .type = NLA_U32 },
2299 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2300 { .type = NLA_U32 },
2301 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2302 { .type = NLA_U32 },
2303 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
2304 { .type = NLA_U8 },
2305 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2306 { .type = NLA_U8 },
2307 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2308 { .type = NLA_U8 },
2309
2310 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2311 { .type = NLA_U32 },
2312 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2313 { .type = NLA_UNSPEC },
2314 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2315 { .type = NLA_S32 },
2316 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2317 { .type = NLA_S32 },
2318 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2319 { .type = NLA_U32 },
2320 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2321 { .type = NLA_U32 },
2322 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
2323 { .type = NLA_U32 },
2324 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
2325 = { .type = NLA_U32 },
2326 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
2327 { .type = NLA_U32 },
2328 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
2329 NLA_U32 },
2330};
2331
2332static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
2333{
2334 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2335 struct sk_buff *skb = NULL;
2336 tpSirEXTScanCapabilitiesEvent pData =
2337 (tpSirEXTScanCapabilitiesEvent) pMsg;
2338
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302339 ENTER();
2340
2341 if (wlan_hdd_validate_context(pHddCtx))
2342 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302343 return;
2344 }
2345
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302346 if (!pMsg)
2347 {
2348 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2349 return;
2350 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302351 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302352#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2353 NULL,
2354#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302355 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2356 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
2357 GFP_KERNEL);
2358
2359 if (!skb) {
2360 hddLog(VOS_TRACE_LEVEL_ERROR,
2361 FL("cfg80211_vendor_event_alloc failed"));
2362 return;
2363 }
2364
2365 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2366 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
2367 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
2368 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
2369 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
2370 pData->maxRssiSampleSize);
2371 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
2372 pData->maxScanReportingThreshold);
2373 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
2374 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
2375 pData->maxSignificantWifiChangeAPs);
2376 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
2377 pData->maxBsidHistoryEntries);
2378
2379 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2380 pData->requestId) ||
2381 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
2382 nla_put_u32(skb,
2383 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
2384 pData->scanCacheSize) ||
2385 nla_put_u32(skb,
2386 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
2387 pData->scanBuckets) ||
2388 nla_put_u32(skb,
2389 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
2390 pData->maxApPerScan) ||
2391 nla_put_u32(skb,
2392 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
2393 pData->maxRssiSampleSize) ||
2394 nla_put_u32(skb,
2395 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
2396 pData->maxScanReportingThreshold) ||
2397 nla_put_u32(skb,
2398 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
2399 pData->maxHotlistAPs) ||
2400 nla_put_u32(skb,
2401 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
2402 pData->maxSignificantWifiChangeAPs) ||
2403 nla_put_u32(skb,
2404 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
2405 pData->maxBsidHistoryEntries)) {
2406 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2407 goto nla_put_failure;
2408 }
2409
2410 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302411 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302412 return;
2413
2414nla_put_failure:
2415 kfree_skb(skb);
2416 return;
2417}
2418
2419
2420static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2421{
2422 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2423 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2424 struct sk_buff *skb = NULL;
2425 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2426
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302427 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302428
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302429 if (wlan_hdd_validate_context(pHddCtx)){
2430 return;
2431 }
2432 if (!pMsg)
2433 {
2434 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302435 return;
2436 }
2437
2438 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302439#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2440 NULL,
2441#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302442 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2443 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2444 GFP_KERNEL);
2445
2446 if (!skb) {
2447 hddLog(VOS_TRACE_LEVEL_ERROR,
2448 FL("cfg80211_vendor_event_alloc failed"));
2449 return;
2450 }
2451 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2452 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2453 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2454
2455 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2456 pData->requestId) ||
2457 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2458 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2459 goto nla_put_failure;
2460 }
2461
2462 /*
2463 * Store the Request ID for comparing with the requestID obtained
2464 * in other requests.HDD shall return a failure is the extscan_stop
2465 * request is issued with a different requestId as that of the
2466 * extscan_start request. Also, This requestId shall be used while
2467 * indicating the full scan results to the upper layers.
2468 * The requestId is stored with the assumption that the firmware
2469 * shall return the ext scan start request's requestId in ext scan
2470 * start response.
2471 */
2472 if (pData->status == 0)
2473 pMac->sme.extScanStartReqId = pData->requestId;
2474
2475
2476 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302477 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302478 return;
2479
2480nla_put_failure:
2481 kfree_skb(skb);
2482 return;
2483}
2484
2485
2486static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2487{
2488 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2489 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2490 struct sk_buff *skb = NULL;
2491
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302492 ENTER();
2493
2494 if (wlan_hdd_validate_context(pHddCtx)){
2495 return;
2496 }
2497 if (!pMsg)
2498 {
2499 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302500 return;
2501 }
2502
2503 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302504#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2505 NULL,
2506#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302507 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2508 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2509 GFP_KERNEL);
2510
2511 if (!skb) {
2512 hddLog(VOS_TRACE_LEVEL_ERROR,
2513 FL("cfg80211_vendor_event_alloc failed"));
2514 return;
2515 }
2516 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2517 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2518
2519 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2520 pData->requestId) ||
2521 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2522 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2523 goto nla_put_failure;
2524 }
2525
2526 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302527 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302528 return;
2529
2530nla_put_failure:
2531 kfree_skb(skb);
2532 return;
2533}
2534
2535
2536static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2537 void *pMsg)
2538{
2539 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2540 struct sk_buff *skb = NULL;
2541 tpSirEXTScanSetBssidHotListRspParams pData =
2542 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2543
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302544 ENTER();
2545
2546 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302547 return;
2548 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302549 if (!pMsg)
2550 {
2551 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2552 return;
2553 }
2554
Dino Mycle6fb96c12014-06-10 11:52:40 +05302555 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302556#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2557 NULL,
2558#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302559 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2560 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2561 GFP_KERNEL);
2562
2563 if (!skb) {
2564 hddLog(VOS_TRACE_LEVEL_ERROR,
2565 FL("cfg80211_vendor_event_alloc failed"));
2566 return;
2567 }
2568 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2569 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2570 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2571
2572 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2573 pData->requestId) ||
2574 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2575 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2576 goto nla_put_failure;
2577 }
2578
2579 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302580 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302581 return;
2582
2583nla_put_failure:
2584 kfree_skb(skb);
2585 return;
2586}
2587
2588static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2589 void *pMsg)
2590{
2591 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2592 struct sk_buff *skb = NULL;
2593 tpSirEXTScanResetBssidHotlistRspParams pData =
2594 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2595
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302596 ENTER();
2597
2598 if (wlan_hdd_validate_context(pHddCtx)) {
2599 return;
2600 }
2601 if (!pMsg)
2602 {
2603 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302604 return;
2605 }
2606
2607 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302608#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2609 NULL,
2610#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302611 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2612 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2613 GFP_KERNEL);
2614
2615 if (!skb) {
2616 hddLog(VOS_TRACE_LEVEL_ERROR,
2617 FL("cfg80211_vendor_event_alloc failed"));
2618 return;
2619 }
2620 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2621 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2622
2623 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2624 pData->requestId) ||
2625 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2626 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2627 goto nla_put_failure;
2628 }
2629
2630 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302631 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302632 return;
2633
2634nla_put_failure:
2635 kfree_skb(skb);
2636 return;
2637}
2638
2639
2640static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2641 void *pMsg)
2642{
2643 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2644 struct sk_buff *skb = NULL;
2645 tpSirEXTScanSetSignificantChangeRspParams pData =
2646 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2647
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302648 ENTER();
2649
2650 if (wlan_hdd_validate_context(pHddCtx)) {
2651 return;
2652 }
2653 if (!pMsg)
2654 {
2655 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302656 return;
2657 }
2658
2659 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302660#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2661 NULL,
2662#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302663 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2664 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2665 GFP_KERNEL);
2666
2667 if (!skb) {
2668 hddLog(VOS_TRACE_LEVEL_ERROR,
2669 FL("cfg80211_vendor_event_alloc failed"));
2670 return;
2671 }
2672 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2673 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2674 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2675
2676 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2677 pData->requestId) ||
2678 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2680 goto nla_put_failure;
2681 }
2682
2683 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302684 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302685 return;
2686
2687nla_put_failure:
2688 kfree_skb(skb);
2689 return;
2690}
2691
2692
2693static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2694 void *pMsg)
2695{
2696 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2697 struct sk_buff *skb = NULL;
2698 tpSirEXTScanResetSignificantChangeRspParams pData =
2699 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2700
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302701 ENTER();
2702
2703 if (wlan_hdd_validate_context(pHddCtx)) {
2704 return;
2705 }
2706 if (!pMsg)
2707 {
2708 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302709 return;
2710 }
2711
2712 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302713#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2714 NULL,
2715#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302716 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2717 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2718 GFP_KERNEL);
2719
2720 if (!skb) {
2721 hddLog(VOS_TRACE_LEVEL_ERROR,
2722 FL("cfg80211_vendor_event_alloc failed"));
2723 return;
2724 }
2725 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2726 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2727 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2728
2729 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2730 pData->requestId) ||
2731 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2732 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2733 goto nla_put_failure;
2734 }
2735
2736 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302737 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302738 return;
2739
2740nla_put_failure:
2741 kfree_skb(skb);
2742 return;
2743}
2744
2745static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2746 void *pMsg)
2747{
2748 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2749 struct sk_buff *skb = NULL;
2750 tANI_U32 i = 0, j, resultsPerEvent;
2751 tANI_S32 totalResults;
2752 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2753 tpSirWifiScanResult pSirWifiScanResult;
2754
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302755 ENTER();
2756
2757 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302758 return;
2759 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302760 if (!pMsg)
2761 {
2762 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2763 return;
2764 }
2765
Dino Mycle6fb96c12014-06-10 11:52:40 +05302766 totalResults = pData->numOfAps;
2767 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2768 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2769 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2770
2771 do{
2772 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2773 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2774 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2775
2776 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302777#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2778 NULL,
2779#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302780 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2781 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2782 GFP_KERNEL);
2783
2784 if (!skb) {
2785 hddLog(VOS_TRACE_LEVEL_ERROR,
2786 FL("cfg80211_vendor_event_alloc failed"));
2787 return;
2788 }
2789
2790 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2791
2792 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2793 pData->requestId) ||
2794 nla_put_u32(skb,
2795 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2796 resultsPerEvent)) {
2797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2798 goto fail;
2799 }
2800 if (nla_put_u8(skb,
2801 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2802 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2803 {
2804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2805 goto fail;
2806 }
2807
2808 if (resultsPerEvent) {
2809 struct nlattr *aps;
2810
2811 aps = nla_nest_start(skb,
2812 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2813 if (!aps)
2814 {
2815 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2816 goto fail;
2817 }
2818
2819 for (j = 0; j < resultsPerEvent; j++, i++) {
2820 struct nlattr *ap;
2821 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2822 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2823
2824 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2825 "Ssid (%s)"
2826 "Bssid: %pM "
2827 "Channel (%u)"
2828 "Rssi (%d)"
2829 "RTT (%u)"
2830 "RTT_SD (%u)",
2831 i,
2832 pSirWifiScanResult->ts,
2833 pSirWifiScanResult->ssid,
2834 pSirWifiScanResult->bssid,
2835 pSirWifiScanResult->channel,
2836 pSirWifiScanResult->rssi,
2837 pSirWifiScanResult->rtt,
2838 pSirWifiScanResult->rtt_sd);
2839
2840 ap = nla_nest_start(skb, j + 1);
2841 if (!ap)
2842 {
2843 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2844 goto fail;
2845 }
2846
2847 if (nla_put_u64(skb,
2848 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2849 pSirWifiScanResult->ts) )
2850 {
2851 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2852 goto fail;
2853 }
2854 if (nla_put(skb,
2855 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2856 sizeof(pSirWifiScanResult->ssid),
2857 pSirWifiScanResult->ssid) )
2858 {
2859 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2860 goto fail;
2861 }
2862 if (nla_put(skb,
2863 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2864 sizeof(pSirWifiScanResult->bssid),
2865 pSirWifiScanResult->bssid) )
2866 {
2867 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2868 goto fail;
2869 }
2870 if (nla_put_u32(skb,
2871 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2872 pSirWifiScanResult->channel) )
2873 {
2874 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2875 goto fail;
2876 }
Dasari Srinivas90747d72014-10-08 12:16:15 +05302877 if (nla_put_s32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302878 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2879 pSirWifiScanResult->rssi) )
2880 {
2881 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2882 goto fail;
2883 }
2884 if (nla_put_u32(skb,
2885 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2886 pSirWifiScanResult->rtt) )
2887 {
2888 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2889 goto fail;
2890 }
2891 if (nla_put_u32(skb,
2892 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2893 pSirWifiScanResult->rtt_sd))
2894 {
2895 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2896 goto fail;
2897 }
2898
2899 nla_nest_end(skb, ap);
2900 }
2901 nla_nest_end(skb, aps);
2902
2903 }
2904 cfg80211_vendor_event(skb, GFP_KERNEL);
2905 } while (totalResults > 0);
2906
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302907 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302908 return;
2909fail:
2910 kfree_skb(skb);
2911 return;
2912}
2913
2914static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2915 void *pMsg)
2916{
2917 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2918 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2919 struct sk_buff *skb = NULL;
2920 tANI_U32 i;
2921
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302922 ENTER();
2923
2924 if (wlan_hdd_validate_context(pHddCtx)) {
2925 return;
2926 }
2927 if (!pMsg)
2928 {
2929 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302930 return;
2931 }
2932
2933 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302934#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2935 NULL,
2936#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302937 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2938 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2939 GFP_KERNEL);
2940
2941 if (!skb) {
2942 hddLog(VOS_TRACE_LEVEL_ERROR,
2943 FL("cfg80211_vendor_event_alloc failed"));
2944 return;
2945 }
2946 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2947 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2948 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2949 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2950
2951 for (i = 0; i < pData->numOfAps; i++) {
2952 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2953 "Ssid (%s) "
2954 "Bssid (" MAC_ADDRESS_STR ") "
2955 "Channel (%u) "
2956 "Rssi (%d) "
2957 "RTT (%u) "
2958 "RTT_SD (%u) ",
2959 i,
2960 pData->ap[i].ts,
2961 pData->ap[i].ssid,
2962 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2963 pData->ap[i].channel,
2964 pData->ap[i].rssi,
2965 pData->ap[i].rtt,
2966 pData->ap[i].rtt_sd);
2967 }
2968
2969 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2970 pData->requestId) ||
2971 nla_put_u32(skb,
2972 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2973 pData->numOfAps)) {
2974 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2975 goto fail;
2976 }
2977 if (pData->numOfAps) {
2978 struct nlattr *aps;
2979
2980 aps = nla_nest_start(skb,
2981 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2982 if (!aps)
2983 goto fail;
2984
2985 for (i = 0; i < pData->numOfAps; i++) {
2986 struct nlattr *ap;
2987
2988 ap = nla_nest_start(skb, i + 1);
2989 if (!ap)
2990 goto fail;
2991
2992 if (nla_put_u64(skb,
2993 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2994 pData->ap[i].ts) ||
2995 nla_put(skb,
2996 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2997 sizeof(pData->ap[i].ssid),
2998 pData->ap[i].ssid) ||
2999 nla_put(skb,
3000 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3001 sizeof(pData->ap[i].bssid),
3002 pData->ap[i].bssid) ||
3003 nla_put_u32(skb,
3004 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3005 pData->ap[i].channel) ||
3006 nla_put_s32(skb,
3007 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3008 pData->ap[i].rssi) ||
3009 nla_put_u32(skb,
3010 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3011 pData->ap[i].rtt) ||
3012 nla_put_u32(skb,
3013 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3014 pData->ap[i].rtt_sd))
3015 goto fail;
3016
3017 nla_nest_end(skb, ap);
3018 }
3019 nla_nest_end(skb, aps);
3020
3021 if (nla_put_u8(skb,
3022 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3023 pData->moreData))
3024 goto fail;
3025 }
3026
3027 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303028 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303029 return;
3030
3031fail:
3032 kfree_skb(skb);
3033 return;
3034
3035}
3036static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
3037 void *pMsg)
3038{
3039 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3040 struct sk_buff *skb = NULL;
3041 tANI_U32 i, j;
3042 tpSirWifiSignificantChangeEvent pData =
3043 (tpSirWifiSignificantChangeEvent) pMsg;
3044
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303045 ENTER();
3046
3047 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303048 return;
3049 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303050 if (!pMsg)
3051 {
3052 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3053 return;
3054 }
3055
Dino Mycle6fb96c12014-06-10 11:52:40 +05303056 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303057#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3058 NULL,
3059#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303060 EXTSCAN_EVENT_BUF_SIZE,
3061 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
3062 GFP_KERNEL);
3063
3064 if (!skb) {
3065 hddLog(VOS_TRACE_LEVEL_ERROR,
3066 FL("cfg80211_vendor_event_alloc failed"));
3067 return;
3068 }
3069 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3070 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3071 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
3072 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
3073 pData->numSigRssiBss);
3074 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
3075
3076 for (i = 0; i < pData->numSigRssiBss; i++) {
3077 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
3078 " num RSSI %u ",
3079 i, pData->sigRssiResult[i].bssid,
3080 pData->sigRssiResult[i].channel,
3081 pData->sigRssiResult[i].numRssi);
3082
3083 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
3084
3085 hddLog(VOS_TRACE_LEVEL_INFO,
3086 " [%d]",
Dino Myclec8f3f332014-07-21 16:48:27 +05303087 pData->sigRssiResult[i].rssi[j]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303088
3089 }
3090 }
3091
3092
3093 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3094 pData->requestId) ||
3095 nla_put_u32(skb,
3096 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3097 pData->numSigRssiBss)) {
3098 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3099 goto fail;
3100 }
3101
3102 if (pData->numSigRssiBss) {
3103 struct nlattr *aps;
3104 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3105 if (!aps)
3106 goto fail;
3107 for (i = 0; i < pData->numSigRssiBss; i++) {
3108 struct nlattr *ap;
3109
3110 ap = nla_nest_start(skb, i);
3111 if (!ap)
3112 goto fail;
3113 if (nla_put(skb,
3114 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
3115 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
3116 nla_put_u32(skb,
3117 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
3118 pData->sigRssiResult[i].channel) ||
3119 nla_put_u32(skb,
3120 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
3121 pData->sigRssiResult[i].numRssi) ||
3122 nla_put(skb,
3123 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
3124 sizeof(s32) * pData->sigRssiResult[i].numRssi,
3125 pData->sigRssiResult[i].rssi))
3126 goto fail;
3127 nla_nest_end(skb, ap);
3128 }
3129 nla_nest_end(skb, aps);
3130 if (nla_put_u8(skb,
3131 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3132 pData->moreData))
3133 goto fail;
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;
3138fail:
3139 kfree_skb(skb);
3140 return;
3141}
3142
3143static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3144 void *pMsg)
3145{
3146 struct sk_buff *skb;
3147 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3148 tpSirWifiFullScanResultEvent pData =
3149 (tpSirWifiFullScanResultEvent) (pMsg);
3150
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303151 ENTER();
3152
3153 if (wlan_hdd_validate_context(pHddCtx)) {
3154 return;
3155 }
3156 if (!pMsg)
3157 {
3158 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303159 return;
3160 }
3161
3162 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303163#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3164 NULL,
3165#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303166 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3167 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3168 GFP_KERNEL);
3169
3170 if (!skb) {
3171 hddLog(VOS_TRACE_LEVEL_ERROR,
3172 FL("cfg80211_vendor_event_alloc failed"));
3173 return;
3174 }
3175
3176 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3177 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3178 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3179 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3180 "Ssid (%s)"
3181 "Bssid (" MAC_ADDRESS_STR ")"
3182 "Channel (%u)"
3183 "Rssi (%d)"
3184 "RTT (%u)"
3185 "RTT_SD (%u)"),
3186 pData->ap.ts,
3187 pData->ap.ssid,
3188 MAC_ADDR_ARRAY(pData->ap.bssid),
3189 pData->ap.channel,
3190 pData->ap.rssi,
3191 pData->ap.rtt,
3192 pData->ap.rtt_sd);
3193 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3194 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3195 pData->requestId) ||
3196 nla_put_u64(skb,
3197 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3198 pData->ap.ts) ||
3199 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3200 sizeof(pData->ap.ssid),
3201 pData->ap.ssid) ||
3202 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3203 WNI_CFG_BSSID_LEN,
3204 pData->ap.bssid) ||
3205 nla_put_u32(skb,
3206 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3207 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303208 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303209 pData->ap.rssi) ||
3210 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3211 pData->ap.rtt) ||
3212 nla_put_u32(skb,
3213 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3214 pData->ap.rtt_sd) ||
3215 nla_put_u16(skb,
3216 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3217 pData->ap.beaconPeriod) ||
3218 nla_put_u16(skb,
3219 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3220 pData->ap.capability) ||
3221 nla_put_u32(skb,
3222 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3223 pData->ieLength))
3224 {
3225 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3226 goto nla_put_failure;
3227 }
3228 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3229 pData->ieLength,
3230 pData->ie))
3231 {
3232 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3233 goto nla_put_failure;
3234 }
3235
3236 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303237 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303238 return;
3239
3240nla_put_failure:
3241 kfree_skb(skb);
3242 return;
3243}
3244
3245static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3246 void *pMsg)
3247{
3248 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3249 struct sk_buff *skb = NULL;
3250 tpSirEXTScanResultsAvailableIndParams pData =
3251 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3252
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303253 ENTER();
3254
3255 if (wlan_hdd_validate_context(pHddCtx)){
3256 return;
3257 }
3258 if (!pMsg)
3259 {
3260 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303261 return;
3262 }
3263
3264 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303265#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3266 NULL,
3267#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303268 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3269 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3270 GFP_KERNEL);
3271
3272 if (!skb) {
3273 hddLog(VOS_TRACE_LEVEL_ERROR,
3274 FL("cfg80211_vendor_event_alloc failed"));
3275 return;
3276 }
3277
3278 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3279 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3280 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3281 pData->numResultsAvailable);
3282 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3283 pData->requestId) ||
3284 nla_put_u32(skb,
3285 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3286 pData->numResultsAvailable)) {
3287 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3288 goto nla_put_failure;
3289 }
3290
3291 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303292 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303293 return;
3294
3295nla_put_failure:
3296 kfree_skb(skb);
3297 return;
3298}
3299
3300static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3301{
3302 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3303 struct sk_buff *skb = NULL;
3304 tpSirEXTScanProgressIndParams pData =
3305 (tpSirEXTScanProgressIndParams) pMsg;
3306
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303307 ENTER();
3308
3309 if (wlan_hdd_validate_context(pHddCtx)){
3310 return;
3311 }
3312 if (!pMsg)
3313 {
3314 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303315 return;
3316 }
3317
3318 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303319#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3320 NULL,
3321#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303322 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3323 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3324 GFP_KERNEL);
3325
3326 if (!skb) {
3327 hddLog(VOS_TRACE_LEVEL_ERROR,
3328 FL("cfg80211_vendor_event_alloc failed"));
3329 return;
3330 }
3331 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3332 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3333 pData->extScanEventType);
3334 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3335 pData->status);
3336
3337 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3338 pData->extScanEventType) ||
3339 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303340 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3341 pData->requestId) ||
3342 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303343 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3344 pData->status)) {
3345 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3346 goto nla_put_failure;
3347 }
3348
3349 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303350 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303351 return;
3352
3353nla_put_failure:
3354 kfree_skb(skb);
3355 return;
3356}
3357
3358void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3359 void *pMsg)
3360{
3361 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3362
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303363 ENTER();
3364
Dino Mycle6fb96c12014-06-10 11:52:40 +05303365 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303366 return;
3367 }
3368
3369 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3370
3371
3372 switch(evType) {
3373 case SIR_HAL_EXTSCAN_START_RSP:
3374 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3375 break;
3376
3377 case SIR_HAL_EXTSCAN_STOP_RSP:
3378 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3379 break;
3380 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3381 /* There is no need to send this response to upper layer
3382 Just log the message */
3383 hddLog(VOS_TRACE_LEVEL_INFO,
3384 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3385 break;
3386 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3387 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3388 break;
3389
3390 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3391 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3392 break;
3393
3394 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
3395 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
3396 break;
3397
3398 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
3399 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
3400 break;
3401 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
3402 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
3403 break;
3404 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3405 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3406 break;
3407 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3408 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3409 break;
3410 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3411 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3412 break;
3413 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3414 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3415 break;
3416 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
3417 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
3418 break;
3419 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3420 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3421 break;
3422 default:
3423 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3424 break;
3425 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303426 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303427}
3428
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303429static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3430 struct wireless_dev *wdev,
3431 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303432{
Dino Myclee8843b32014-07-04 14:21:45 +05303433 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303434 struct net_device *dev = wdev->netdev;
3435 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3436 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3437 struct nlattr
3438 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3439 eHalStatus status;
3440
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303441 ENTER();
3442
Dino Mycle6fb96c12014-06-10 11:52:40 +05303443 status = wlan_hdd_validate_context(pHddCtx);
3444 if (0 != status)
3445 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303446 return -EINVAL;
3447 }
Dino Myclee8843b32014-07-04 14:21:45 +05303448 /* check the EXTScan Capability */
3449 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3450 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3451 {
3452 hddLog(VOS_TRACE_LEVEL_ERROR,
3453 FL("EXTScan not enabled/supported by Firmware"));
3454 return -EINVAL;
3455 }
3456
Dino Mycle6fb96c12014-06-10 11:52:40 +05303457 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3458 data, dataLen,
3459 wlan_hdd_extscan_config_policy)) {
3460 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3461 return -EINVAL;
3462 }
3463
3464 /* Parse and fetch request Id */
3465 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3466 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3467 return -EINVAL;
3468 }
3469
Dino Mycle6fb96c12014-06-10 11:52:40 +05303470
Dino Myclee8843b32014-07-04 14:21:45 +05303471 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303472 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303473 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303474
Dino Myclee8843b32014-07-04 14:21:45 +05303475 reqMsg.sessionId = pAdapter->sessionId;
3476 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303477
Dino Myclee8843b32014-07-04 14:21:45 +05303478 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303479 if (!HAL_STATUS_SUCCESS(status)) {
3480 hddLog(VOS_TRACE_LEVEL_ERROR,
3481 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303482 return -EINVAL;
3483 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303484 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303485 return 0;
3486}
3487
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303488static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3489 struct wireless_dev *wdev,
3490 const void *data, int dataLen)
3491{
3492 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303493
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303494 vos_ssr_protect(__func__);
3495 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3496 vos_ssr_unprotect(__func__);
3497
3498 return ret;
3499}
3500
3501static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3502 struct wireless_dev *wdev,
3503 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303504{
Dino Myclee8843b32014-07-04 14:21:45 +05303505 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303506 struct net_device *dev = wdev->netdev;
3507 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3508 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3509 struct nlattr
3510 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3511 eHalStatus status;
3512
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303513 ENTER();
3514
Dino Mycle6fb96c12014-06-10 11:52:40 +05303515 status = wlan_hdd_validate_context(pHddCtx);
3516 if (0 != status)
3517 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303518 return -EINVAL;
3519 }
Dino Myclee8843b32014-07-04 14:21:45 +05303520 /* check the EXTScan Capability */
3521 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3522 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3523 {
3524 hddLog(VOS_TRACE_LEVEL_ERROR,
3525 FL("EXTScan not enabled/supported by Firmware"));
3526 return -EINVAL;
3527 }
3528
Dino Mycle6fb96c12014-06-10 11:52:40 +05303529 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3530 data, dataLen,
3531 wlan_hdd_extscan_config_policy)) {
3532 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3533 return -EINVAL;
3534 }
3535 /* Parse and fetch request Id */
3536 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3537 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3538 return -EINVAL;
3539 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303540
Dino Myclee8843b32014-07-04 14:21:45 +05303541 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303542 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3543
Dino Myclee8843b32014-07-04 14:21:45 +05303544 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303545
Dino Myclee8843b32014-07-04 14:21:45 +05303546 reqMsg.sessionId = pAdapter->sessionId;
3547 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303548
3549 /* Parse and fetch flush parameter */
3550 if (!tb
3551 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3552 {
3553 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3554 goto failed;
3555 }
Dino Myclee8843b32014-07-04 14:21:45 +05303556 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303557 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3558
Dino Myclee8843b32014-07-04 14:21:45 +05303559 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303560
Dino Myclee8843b32014-07-04 14:21:45 +05303561 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303562 if (!HAL_STATUS_SUCCESS(status)) {
3563 hddLog(VOS_TRACE_LEVEL_ERROR,
3564 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303565 return -EINVAL;
3566 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303567 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303568 return 0;
3569
3570failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303571 return -EINVAL;
3572}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303573static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3574 struct wireless_dev *wdev,
3575 const void *data, int dataLen)
3576{
3577 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303578
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303579 vos_ssr_protect(__func__);
3580 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3581 vos_ssr_unprotect(__func__);
3582
3583 return ret;
3584}
3585
3586static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303587 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303588 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303589{
3590 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3591 struct net_device *dev = wdev->netdev;
3592 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3593 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3594 struct nlattr
3595 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3596 struct nlattr
3597 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3598 struct nlattr *apTh;
3599 eHalStatus status;
3600 tANI_U8 i = 0;
3601 int rem;
3602
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303603 ENTER();
3604
Dino Mycle6fb96c12014-06-10 11:52:40 +05303605 status = wlan_hdd_validate_context(pHddCtx);
3606 if (0 != status)
3607 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303608 return -EINVAL;
3609 }
Dino Myclee8843b32014-07-04 14:21:45 +05303610 /* check the EXTScan Capability */
3611 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3612 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3613 {
3614 hddLog(VOS_TRACE_LEVEL_ERROR,
3615 FL("EXTScan not enabled/supported by Firmware"));
3616 return -EINVAL;
3617 }
3618
Dino Mycle6fb96c12014-06-10 11:52:40 +05303619 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3620 data, dataLen,
3621 wlan_hdd_extscan_config_policy)) {
3622 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3623 return -EINVAL;
3624 }
3625
3626 /* Parse and fetch request Id */
3627 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3628 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3629 return -EINVAL;
3630 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303631 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3632 vos_mem_malloc(sizeof(*pReqMsg));
3633 if (!pReqMsg) {
3634 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3635 return -ENOMEM;
3636 }
3637
Dino Myclee8843b32014-07-04 14:21:45 +05303638
Dino Mycle6fb96c12014-06-10 11:52:40 +05303639 pReqMsg->requestId = nla_get_u32(
3640 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3641 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3642
3643 /* Parse and fetch number of APs */
3644 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3645 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3646 goto fail;
3647 }
3648
3649 pReqMsg->sessionId = pAdapter->sessionId;
3650 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3651
3652 pReqMsg->numAp = nla_get_u32(
3653 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3654 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3655
3656 nla_for_each_nested(apTh,
3657 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3658 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3659 nla_data(apTh), nla_len(apTh),
3660 NULL)) {
3661 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3662 goto fail;
3663 }
3664
3665 /* Parse and fetch MAC address */
3666 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3668 goto fail;
3669 }
3670 memcpy(pReqMsg->ap[i].bssid, nla_data(
3671 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3672 sizeof(tSirMacAddr));
3673 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3674
3675 /* Parse and fetch low RSSI */
3676 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3677 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3678 goto fail;
3679 }
3680 pReqMsg->ap[i].low = nla_get_s32(
3681 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3682 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3683
3684 /* Parse and fetch high RSSI */
3685 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3686 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3687 goto fail;
3688 }
3689 pReqMsg->ap[i].high = nla_get_s32(
3690 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3691 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3692 pReqMsg->ap[i].high);
3693
3694 /* Parse and fetch channel */
3695 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3696 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3697 goto fail;
3698 }
3699 pReqMsg->ap[i].channel = nla_get_u32(
3700 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3701 hddLog(VOS_TRACE_LEVEL_INFO,
3702 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3703 i++;
3704 }
3705 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3706 if (!HAL_STATUS_SUCCESS(status)) {
3707 hddLog(VOS_TRACE_LEVEL_ERROR,
3708 FL("sme_SetBssHotlist failed(err=%d)"), status);
3709 vos_mem_free(pReqMsg);
3710 return -EINVAL;
3711 }
3712
Dino Myclee8843b32014-07-04 14:21:45 +05303713 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303714 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303715 return 0;
3716
3717fail:
3718 vos_mem_free(pReqMsg);
3719 return -EINVAL;
3720}
3721
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303722static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3723 struct wireless_dev *wdev,
3724 const void *data, int dataLen)
3725{
3726 int ret = 0;
3727
3728 vos_ssr_protect(__func__);
3729 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3730 dataLen);
3731 vos_ssr_unprotect(__func__);
3732
3733 return ret;
3734}
3735
3736static int __wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303737 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303738 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303739{
3740 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3741 struct net_device *dev = wdev->netdev;
3742 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3743 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3744 struct nlattr
3745 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3746 struct nlattr
3747 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3748 struct nlattr *apTh;
3749 eHalStatus status;
3750 int i = 0;
3751 int rem;
3752
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303753 ENTER();
3754
Dino Mycle6fb96c12014-06-10 11:52:40 +05303755 status = wlan_hdd_validate_context(pHddCtx);
3756 if (0 != status)
3757 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303758 return -EINVAL;
3759 }
Dino Myclee8843b32014-07-04 14:21:45 +05303760 /* check the EXTScan Capability */
3761 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3762 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3763 {
3764 hddLog(VOS_TRACE_LEVEL_ERROR,
3765 FL("EXTScan not enabled/supported by Firmware"));
3766 return -EINVAL;
3767 }
3768
Dino Mycle6fb96c12014-06-10 11:52:40 +05303769 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3770 data, dataLen,
3771 wlan_hdd_extscan_config_policy)) {
3772 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3773 return -EINVAL;
3774 }
3775
3776 /* Parse and fetch request Id */
3777 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3778 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3779 return -EINVAL;
3780 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303781 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303782 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303783 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303784 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3785 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303786 }
3787
Dino Myclee8843b32014-07-04 14:21:45 +05303788
3789
Dino Mycle6fb96c12014-06-10 11:52:40 +05303790 pReqMsg->requestId = nla_get_u32(
3791 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3792 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3793
3794 /* Parse and fetch RSSI sample size */
3795 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3796 {
3797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3798 goto fail;
3799 }
3800 pReqMsg->rssiSampleSize = nla_get_u32(
3801 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3802 hddLog(VOS_TRACE_LEVEL_INFO,
3803 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3804
3805 /* Parse and fetch lost AP sample size */
3806 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3807 {
3808 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3809 goto fail;
3810 }
3811 pReqMsg->lostApSampleSize = nla_get_u32(
3812 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3813 hddLog(VOS_TRACE_LEVEL_INFO,
3814 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3815 /* Parse and fetch minimum Breaching */
3816 if (!tb
3817 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3818 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3819 goto fail;
3820 }
3821 pReqMsg->minBreaching = nla_get_u32(
3822 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3823 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3824
3825 /* Parse and fetch number of APs */
3826 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3827 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3828 goto fail;
3829 }
3830 pReqMsg->numAp = nla_get_u32(
3831 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3832 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3833
3834 pReqMsg->sessionId = pAdapter->sessionId;
3835 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3836
3837 nla_for_each_nested(apTh,
3838 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3839 if(nla_parse(tb2,
3840 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3841 nla_data(apTh), nla_len(apTh),
3842 NULL)) {
3843 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3844 goto fail;
3845 }
3846
3847 /* Parse and fetch MAC address */
3848 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3849 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3850 goto fail;
3851 }
3852 memcpy(pReqMsg->ap[i].bssid, nla_data(
3853 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3854 sizeof(tSirMacAddr));
3855
3856 /* Parse and fetch low RSSI */
3857 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3858 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3859 goto fail;
3860 }
3861 pReqMsg->ap[i].low = nla_get_s32(
3862 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3863 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3864
3865 /* Parse and fetch high RSSI */
3866 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3867 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3868 goto fail;
3869 }
3870 pReqMsg->ap[i].high = nla_get_s32(
3871 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3872 hddLog(VOS_TRACE_LEVEL_INFO,
3873 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3874
3875 /* Parse and fetch channel */
3876 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3877 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3878 goto fail;
3879 }
3880 pReqMsg->ap[i].channel = nla_get_u32(
3881 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3882 hddLog(VOS_TRACE_LEVEL_INFO,
3883 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3884 i++;
3885 }
3886
3887 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3888 if (!HAL_STATUS_SUCCESS(status)) {
3889 hddLog(VOS_TRACE_LEVEL_ERROR,
3890 FL("sme_SetSignificantChange failed(err=%d)"), status);
3891 vos_mem_free(pReqMsg);
3892 return -EINVAL;
3893 }
Dino Myclee8843b32014-07-04 14:21:45 +05303894 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303895 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303896 return 0;
3897
3898fail:
3899 vos_mem_free(pReqMsg);
3900 return -EINVAL;
3901}
3902
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303903static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3904 struct wireless_dev *wdev,
3905 const void *data, int dataLen)
3906{
3907 int ret = 0;
3908
3909 vos_ssr_protect(__func__);
3910 ret = __wlan_hdd_cfg80211_extscan_set_significant_change(wiphy, wdev, data,
3911 dataLen);
3912 vos_ssr_unprotect(__func__);
3913
3914 return ret;
3915}
3916
3917static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303918 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303919 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303920{
3921 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3922 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3923 tANI_U8 numChannels = 0;
3924 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3925 tANI_U32 requestId;
3926 tWifiBand wifiBand;
3927 eHalStatus status;
3928 struct sk_buff *replySkb;
3929 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303930 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303931
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303932 ENTER();
3933
Dino Mycle6fb96c12014-06-10 11:52:40 +05303934 status = wlan_hdd_validate_context(pHddCtx);
3935 if (0 != status)
3936 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303937 return -EINVAL;
3938 }
Dino Myclee8843b32014-07-04 14:21:45 +05303939
Dino Mycle6fb96c12014-06-10 11:52:40 +05303940 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3941 data, dataLen,
3942 wlan_hdd_extscan_config_policy)) {
3943 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3944 return -EINVAL;
3945 }
3946
3947 /* Parse and fetch request Id */
3948 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3949 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3950 return -EINVAL;
3951 }
3952 requestId = nla_get_u32(
3953 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3954 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3955
3956 /* Parse and fetch wifi band */
3957 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3958 {
3959 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3960 return -EINVAL;
3961 }
3962 wifiBand = nla_get_u32(
3963 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3964 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3965
3966 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3967 wifiBand, ChannelList,
3968 &numChannels);
3969 if (eHAL_STATUS_SUCCESS != status) {
3970 hddLog(VOS_TRACE_LEVEL_ERROR,
3971 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3972 return -EINVAL;
3973 }
3974 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3975 for (i = 0; i < numChannels; i++)
3976 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3977
3978 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3979 sizeof(u32) * numChannels +
3980 NLMSG_HDRLEN);
3981
3982 if (!replySkb) {
3983 hddLog(VOS_TRACE_LEVEL_ERROR,
3984 FL("valid channels: buffer alloc fail"));
3985 return -EINVAL;
3986 }
3987 if (nla_put_u32(replySkb,
3988 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3989 numChannels) ||
3990 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3991 sizeof(u32) * numChannels, ChannelList)) {
3992
3993 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3994 kfree_skb(replySkb);
3995 return -EINVAL;
3996 }
3997
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303998 ret = cfg80211_vendor_cmd_reply(replySkb);
3999
4000 EXIT();
4001 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304002}
4003
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304004static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4005 struct wireless_dev *wdev,
4006 const void *data, int dataLen)
4007{
4008 int ret = 0;
4009
4010 vos_ssr_protect(__func__);
4011 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4012 dataLen);
4013 vos_ssr_unprotect(__func__);
4014
4015 return ret;
4016}
4017
4018static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304019 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304020 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304021{
Dino Myclee8843b32014-07-04 14:21:45 +05304022 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304023 struct net_device *dev = wdev->netdev;
4024 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4025 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4026 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4027 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4028 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4029 struct nlattr *buckets;
4030 struct nlattr *channels;
4031 int rem1;
4032 int rem2;
4033 eHalStatus status;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304034 tANI_U32 j = 0, index = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304035
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304036 ENTER();
4037
Dino Mycle6fb96c12014-06-10 11:52:40 +05304038 status = wlan_hdd_validate_context(pHddCtx);
4039 if (0 != status)
4040 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304041 return -EINVAL;
4042 }
Dino Myclee8843b32014-07-04 14:21:45 +05304043 /* check the EXTScan Capability */
4044 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4045 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4046 {
4047 hddLog(VOS_TRACE_LEVEL_ERROR,
4048 FL("EXTScan not enabled/supported by Firmware"));
4049 return -EINVAL;
4050 }
4051
Dino Mycle6fb96c12014-06-10 11:52:40 +05304052 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4053 data, dataLen,
4054 wlan_hdd_extscan_config_policy)) {
4055 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4056 return -EINVAL;
4057 }
4058
4059 /* Parse and fetch request Id */
4060 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4061 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4062 return -EINVAL;
4063 }
4064
Dino Myclee8843b32014-07-04 14:21:45 +05304065 pReqMsg = (tpSirEXTScanStartReqParams)
4066 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304067 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304068 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4069 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304070 }
4071
4072 pReqMsg->requestId = nla_get_u32(
4073 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4074 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4075
4076 pReqMsg->sessionId = pAdapter->sessionId;
4077 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4078
4079 /* Parse and fetch base period */
4080 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
4081 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4082 goto fail;
4083 }
4084 pReqMsg->basePeriod = nla_get_u32(
4085 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
4086 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4087 pReqMsg->basePeriod);
4088
4089 /* Parse and fetch max AP per scan */
4090 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
4091 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4092 goto fail;
4093 }
4094 pReqMsg->maxAPperScan = nla_get_u32(
4095 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
4096 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4097 pReqMsg->maxAPperScan);
4098
4099 /* Parse and fetch report threshold */
4100 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
4101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4102 goto fail;
4103 }
4104 pReqMsg->reportThreshold = nla_get_u8(
4105 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
4106 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
4107 pReqMsg->reportThreshold);
4108
4109 /* Parse and fetch number of buckets */
4110 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
4111 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4112 goto fail;
4113 }
4114 pReqMsg->numBuckets = nla_get_u8(
4115 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
4116 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4117 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4118 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4119 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4120 }
4121 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4122 pReqMsg->numBuckets);
4123 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4124 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4125 goto fail;
4126 }
4127
4128 nla_for_each_nested(buckets,
4129 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4130 if(nla_parse(bucket,
4131 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4132 nla_data(buckets), nla_len(buckets), NULL)) { //policy
4133 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4134 goto fail;
4135 }
4136
4137 /* Parse and fetch bucket spec */
4138 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4139 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
4140 goto fail;
4141 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304142
4143 pReqMsg->buckets[index].bucket = nla_get_u8(
4144 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4145
4146 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"),
4147 pReqMsg->buckets[index].bucket);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304148
4149 /* Parse and fetch wifi band */
4150 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4151 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4152 goto fail;
4153 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304154 pReqMsg->buckets[index].band = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304155 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4156 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304157 pReqMsg->buckets[index].band);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304158
4159 /* Parse and fetch period */
4160 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4161 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
4162 goto fail;
4163 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304164 pReqMsg->buckets[index].period = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304165 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4166 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304167 pReqMsg->buckets[index].period);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304168
4169 /* Parse and fetch report events */
4170 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4171 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
4172 goto fail;
4173 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304174 pReqMsg->buckets[index].reportEvents = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304175 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4176 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304177 pReqMsg->buckets[index].reportEvents);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304178
4179 /* Parse and fetch number of channels */
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304180 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS])
4181 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304182 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
4183 goto fail;
4184 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304185 pReqMsg->buckets[index].numChannels = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304186 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4187 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304188 pReqMsg->buckets[index].numChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304189
4190 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4191 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
4192 goto fail;
4193 }
4194
4195 j = 0;
4196 nla_for_each_nested(channels,
4197 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4198 if(nla_parse(channel,
4199 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4200 nla_data(channels), nla_len(channels),
4201 NULL)) { //wlan_hdd_extscan_config_policy here
4202 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4203 goto fail;
4204 }
4205
4206 /* Parse and fetch channel */
4207 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4208 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4209 goto fail;
4210 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304211 pReqMsg->buckets[index].channels[j].channel = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304212 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4213 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304214 pReqMsg->buckets[index].channels[j].channel);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304215
4216 /* Parse and fetch dwell time */
4217 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4218 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
4219 goto fail;
4220 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304221 pReqMsg->buckets[index].channels[j].dwellTimeMs = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304222 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4223 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304224 pReqMsg->buckets[index].channels[j].dwellTimeMs);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304225
4226 /* Parse and fetch channel spec passive */
4227 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4228 hddLog(VOS_TRACE_LEVEL_ERROR,
4229 FL("attr channel spec passive failed"));
4230 goto fail;
4231 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304232 pReqMsg->buckets[index].channels[j].passive = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304233 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4234 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304235 pReqMsg->buckets[index].channels[j].passive);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304236 j++;
4237 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304238 index++;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304239 }
4240 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4241 if (!HAL_STATUS_SUCCESS(status)) {
4242 hddLog(VOS_TRACE_LEVEL_ERROR,
4243 FL("sme_EXTScanStart failed(err=%d)"), status);
4244 vos_mem_free(pReqMsg);
4245 return -EINVAL;
4246 }
4247
Dino Myclee8843b32014-07-04 14:21:45 +05304248 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304249 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304250 return 0;
4251
4252fail:
4253 vos_mem_free(pReqMsg);
4254 return -EINVAL;
4255}
4256
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304257static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4258 struct wireless_dev *wdev,
4259 const void *data, int dataLen)
4260{
4261 int ret = 0;
4262
4263 vos_ssr_protect(__func__);
4264 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4265 vos_ssr_unprotect(__func__);
4266
4267 return ret;
4268}
4269
4270static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304271 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304272 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304273{
Dino Myclee8843b32014-07-04 14:21:45 +05304274 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304275 struct net_device *dev = wdev->netdev;
4276 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4277 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4278 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4279 eHalStatus status;
4280
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304281 ENTER();
4282
Dino Mycle6fb96c12014-06-10 11:52:40 +05304283 status = wlan_hdd_validate_context(pHddCtx);
4284 if (0 != status)
4285 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304286 return -EINVAL;
4287 }
Dino Myclee8843b32014-07-04 14:21:45 +05304288 /* check the EXTScan Capability */
4289 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4290 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4291 {
4292 hddLog(VOS_TRACE_LEVEL_ERROR,
4293 FL("EXTScan not enabled/supported by Firmware"));
4294 return -EINVAL;
4295 }
4296
Dino Mycle6fb96c12014-06-10 11:52:40 +05304297 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4298 data, dataLen,
4299 wlan_hdd_extscan_config_policy)) {
4300 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4301 return -EINVAL;
4302 }
4303
4304 /* Parse and fetch request Id */
4305 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4306 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4307 return -EINVAL;
4308 }
4309
Dino Myclee8843b32014-07-04 14:21:45 +05304310 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304311 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304312 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304313
Dino Myclee8843b32014-07-04 14:21:45 +05304314 reqMsg.sessionId = pAdapter->sessionId;
4315 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304316
Dino Myclee8843b32014-07-04 14:21:45 +05304317 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304318 if (!HAL_STATUS_SUCCESS(status)) {
4319 hddLog(VOS_TRACE_LEVEL_ERROR,
4320 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304321 return -EINVAL;
4322 }
4323
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304324 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304325 return 0;
4326}
4327
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304328static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4329 struct wireless_dev *wdev,
4330 const void *data, int dataLen)
4331{
4332 int ret = 0;
4333
4334 vos_ssr_protect(__func__);
4335 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4336 vos_ssr_unprotect(__func__);
4337
4338 return ret;
4339}
4340
4341static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304342 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304343 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304344{
Dino Myclee8843b32014-07-04 14:21:45 +05304345 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304346 struct net_device *dev = wdev->netdev;
4347 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4348 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4349 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4350 eHalStatus status;
4351
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304352 ENTER();
4353
Dino Mycle6fb96c12014-06-10 11:52:40 +05304354 status = wlan_hdd_validate_context(pHddCtx);
4355 if (0 != status)
4356 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304357 return -EINVAL;
4358 }
Dino Myclee8843b32014-07-04 14:21:45 +05304359 /* check the EXTScan Capability */
4360 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4361 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4362 {
4363 hddLog(VOS_TRACE_LEVEL_ERROR,
4364 FL("EXTScan not enabled/supported by Firmware"));
4365 return -EINVAL;
4366 }
4367
Dino Mycle6fb96c12014-06-10 11:52:40 +05304368 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4369 data, dataLen,
4370 wlan_hdd_extscan_config_policy)) {
4371 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4372 return -EINVAL;
4373 }
4374
4375 /* Parse and fetch request Id */
4376 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4377 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4378 return -EINVAL;
4379 }
4380
Dino Myclee8843b32014-07-04 14:21:45 +05304381 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304382 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304383 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304384
Dino Myclee8843b32014-07-04 14:21:45 +05304385 reqMsg.sessionId = pAdapter->sessionId;
4386 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304387
Dino Myclee8843b32014-07-04 14:21:45 +05304388 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304389 if (!HAL_STATUS_SUCCESS(status)) {
4390 hddLog(VOS_TRACE_LEVEL_ERROR,
4391 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304392 return -EINVAL;
4393 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304394 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304395 return 0;
4396}
4397
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304398static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4399 struct wireless_dev *wdev,
4400 const void *data, int dataLen)
4401{
4402 int ret = 0;
4403
4404 vos_ssr_protect(__func__);
4405 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4406 vos_ssr_unprotect(__func__);
4407
4408 return ret;
4409}
4410
4411static int __wlan_hdd_cfg80211_extscan_reset_significant_change(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304412 struct wiphy *wiphy,
4413 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304414 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304415{
Dino Myclee8843b32014-07-04 14:21:45 +05304416 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304417 struct net_device *dev = wdev->netdev;
4418 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4419 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4420 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4421 eHalStatus status;
4422
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304423 ENTER();
4424
Dino Mycle6fb96c12014-06-10 11:52:40 +05304425 status = wlan_hdd_validate_context(pHddCtx);
4426 if (0 != status)
4427 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304428 return -EINVAL;
4429 }
Dino Myclee8843b32014-07-04 14:21:45 +05304430 /* check the EXTScan Capability */
4431 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4432 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4433 {
4434 hddLog(VOS_TRACE_LEVEL_ERROR,
4435 FL("EXTScan not enabled/supported by Firmware"));
4436 return -EINVAL;
4437 }
4438
Dino Mycle6fb96c12014-06-10 11:52:40 +05304439 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4440 data, dataLen,
4441 wlan_hdd_extscan_config_policy)) {
4442 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4443 return -EINVAL;
4444 }
4445
4446 /* Parse and fetch request Id */
4447 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4448 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4449 return -EINVAL;
4450 }
4451
Dino Mycle6fb96c12014-06-10 11:52:40 +05304452
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_ResetSignificantChange(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_ResetSignificantChange 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_reset_significant_change(
4472 struct wiphy *wiphy,
4473 struct wireless_dev *wdev,
4474 const void *data, int dataLen)
4475{
4476 int ret = 0;
4477
4478 vos_ssr_protect(__func__);
4479 ret = __wlan_hdd_cfg80211_extscan_reset_significant_change(wiphy,
4480 wdev, data,
4481 dataLen);
4482 vos_ssr_unprotect(__func__);
4483
4484 return ret;
4485}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304486#endif /* WLAN_FEATURE_EXTSCAN */
4487
Atul Mittal115287b2014-07-08 13:26:33 +05304488/*EXT TDLS*/
4489static const struct nla_policy
4490wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4491{
4492 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4493 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4494 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4495 {.type = NLA_S32 },
4496 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4497 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4498
4499};
4500
4501static const struct nla_policy
4502wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4503{
4504 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4505
4506};
4507
4508static const struct nla_policy
4509wlan_hdd_tdls_config_state_change_policy[
4510 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4511{
4512 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4513 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4514 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304515 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4516 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4517 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304518
4519};
4520
4521static const struct nla_policy
4522wlan_hdd_tdls_config_get_status_policy[
4523 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4524{
4525 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4526 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4527 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304528 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4529 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4530 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304531
4532};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304533
4534static const struct nla_policy
4535wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4536{
4537 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
4538};
4539
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304540static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304541 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304542 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304543 int data_len)
4544{
4545
4546 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4547 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
4548
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304549 ENTER();
4550
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304551 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304552 return -EINVAL;
4553 }
4554 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
4555 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN disabled in ini"));
4556 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05304557 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304558 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
4559 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN not supported by FW"));
4560 return -ENOTSUPP;
4561 }
4562
4563 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
4564 data, data_len, wlan_hdd_mac_config)) {
4565 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4566 return -EINVAL;
4567 }
4568
4569 /* Parse and fetch mac address */
4570 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
4571 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4572 return -EINVAL;
4573 }
4574
4575 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
4576 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4577 VOS_MAC_ADDR_LAST_3_BYTES);
4578
Siddharth Bhal76972212014-10-15 16:22:51 +05304579 pHddCtx->spoofMacAddr.isEnabled = TRUE;
4580
4581 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304582 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4583 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05304584 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
4585 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
4586 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
4587 {
4588 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
4589 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
4590 VOS_MAC_ADDRESS_LEN);
4591 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304592 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304593
Siddharth Bhal76972212014-10-15 16:22:51 +05304594 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
4595 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304596 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
4597 }
4598
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304599 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304600 return 0;
4601}
4602
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304603static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
4604 struct wireless_dev *wdev,
4605 const void *data,
4606 int data_len)
4607{
4608 int ret = 0;
4609
4610 vos_ssr_protect(__func__);
4611 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
4612 vos_ssr_unprotect(__func__);
4613
4614 return ret;
4615}
4616
4617static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304618 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304619 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304620 int data_len)
4621{
4622 u8 peer[6] = {0};
4623 struct net_device *dev = wdev->netdev;
4624 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4625 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4626 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
4627 eHalStatus ret;
4628 tANI_S32 state;
4629 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304630 tANI_S32 global_operating_class = 0;
4631 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304632 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304633 int retVal;
4634
4635 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304636
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304637 if (!pAdapter) {
4638 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4639 return -EINVAL;
4640 }
4641
Atul Mittal115287b2014-07-08 13:26:33 +05304642 ret = wlan_hdd_validate_context(pHddCtx);
4643 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304644 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304645 return -EINVAL;
4646 }
4647 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304648 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304649 return -ENOTSUPP;
4650 }
4651 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4652 data, data_len,
4653 wlan_hdd_tdls_config_get_status_policy)) {
4654 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4655 return -EINVAL;
4656 }
4657
4658 /* Parse and fetch mac address */
4659 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4660 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4661 return -EINVAL;
4662 }
4663
4664 memcpy(peer, nla_data(
4665 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4666 sizeof(peer));
4667 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4668
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05304669 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05304670
Atul Mittal115287b2014-07-08 13:26:33 +05304671 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304672 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05304673 NLMSG_HDRLEN);
4674
4675 if (!skb) {
4676 hddLog(VOS_TRACE_LEVEL_ERROR,
4677 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4678 return -EINVAL;
4679 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304680 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 +05304681 reason,
4682 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304683 global_operating_class,
4684 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05304685 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304686 if (nla_put_s32(skb,
4687 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
4688 state) ||
4689 nla_put_s32(skb,
4690 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
4691 reason) ||
4692 nla_put_s32(skb,
4693 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
4694 global_operating_class) ||
4695 nla_put_s32(skb,
4696 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
4697 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304698
4699 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4700 goto nla_put_failure;
4701 }
4702
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304703 retVal = cfg80211_vendor_cmd_reply(skb);
4704 EXIT();
4705 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05304706
4707nla_put_failure:
4708 kfree_skb(skb);
4709 return -EINVAL;
4710}
4711
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304712static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
4713 struct wireless_dev *wdev,
4714 const void *data,
4715 int data_len)
4716{
4717 int ret = 0;
4718
4719 vos_ssr_protect(__func__);
4720 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
4721 vos_ssr_unprotect(__func__);
4722
4723 return ret;
4724}
4725
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05304726static int wlan_hdd_cfg80211_exttdls_callback(
4727#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
4728 const tANI_U8* mac,
4729#else
4730 tANI_U8* mac,
4731#endif
Atul Mittal115287b2014-07-08 13:26:33 +05304732 tANI_S32 state,
4733 tANI_S32 reason,
4734 void *ctx)
4735{
4736 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05304737 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304738 tANI_S32 global_operating_class = 0;
4739 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304740 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05304741
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304742 ENTER();
4743
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304744 if (!pAdapter) {
4745 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4746 return -EINVAL;
4747 }
4748
4749 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05304750 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304751 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304752 return -EINVAL;
4753 }
4754
4755 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304756 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304757 return -ENOTSUPP;
4758 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304759 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
4760#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4761 NULL,
4762#endif
Atul Mittal115287b2014-07-08 13:26:33 +05304763 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4764 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4765 GFP_KERNEL);
4766
4767 if (!skb) {
4768 hddLog(VOS_TRACE_LEVEL_ERROR,
4769 FL("cfg80211_vendor_event_alloc failed"));
4770 return -EINVAL;
4771 }
4772 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304773 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
4774 reason,
4775 state,
4776 global_operating_class,
4777 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05304778 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4779 MAC_ADDR_ARRAY(mac));
4780
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304781 if (nla_put(skb,
4782 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4783 VOS_MAC_ADDR_SIZE, mac) ||
4784 nla_put_s32(skb,
4785 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
4786 state) ||
4787 nla_put_s32(skb,
4788 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
4789 reason) ||
4790 nla_put_s32(skb,
4791 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
4792 channel) ||
4793 nla_put_s32(skb,
4794 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
4795 global_operating_class)
4796 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05304797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4798 goto nla_put_failure;
4799 }
4800
4801 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304802 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05304803 return (0);
4804
4805nla_put_failure:
4806 kfree_skb(skb);
4807 return -EINVAL;
4808}
4809
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304810static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304811 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304812 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304813 int data_len)
4814{
4815 u8 peer[6] = {0};
4816 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304817 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4818 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4819 eHalStatus status;
4820 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304821 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304822 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304823
4824 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304825
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304826 if (!dev) {
4827 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4828 return -EINVAL;
4829 }
4830
4831 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4832 if (!pAdapter) {
4833 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4834 return -EINVAL;
4835 }
4836
Atul Mittal115287b2014-07-08 13:26:33 +05304837 status = wlan_hdd_validate_context(pHddCtx);
4838 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304839 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304840 return -EINVAL;
4841 }
4842 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304843 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304844 return -ENOTSUPP;
4845 }
4846 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4847 data, data_len,
4848 wlan_hdd_tdls_config_enable_policy)) {
4849 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4850 return -EINVAL;
4851 }
4852
4853 /* Parse and fetch mac address */
4854 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4855 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4856 return -EINVAL;
4857 }
4858
4859 memcpy(peer, nla_data(
4860 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4861 sizeof(peer));
4862 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4863
4864 /* Parse and fetch channel */
4865 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4866 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4867 return -EINVAL;
4868 }
4869 pReqMsg.channel = nla_get_s32(
4870 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4871 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4872
4873 /* Parse and fetch global operating class */
4874 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4875 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4876 return -EINVAL;
4877 }
4878 pReqMsg.global_operating_class = nla_get_s32(
4879 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4880 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4881 pReqMsg.global_operating_class);
4882
4883 /* Parse and fetch latency ms */
4884 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4885 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4886 return -EINVAL;
4887 }
4888 pReqMsg.max_latency_ms = nla_get_s32(
4889 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4890 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4891 pReqMsg.max_latency_ms);
4892
4893 /* Parse and fetch required bandwidth kbps */
4894 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4895 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4896 return -EINVAL;
4897 }
4898
4899 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4900 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4901 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4902 pReqMsg.min_bandwidth_kbps);
4903
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304904 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05304905 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05304906 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304907 wlan_hdd_cfg80211_exttdls_callback);
4908
4909 EXIT();
4910 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304911}
4912
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304913static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4914 struct wireless_dev *wdev,
4915 const void *data,
4916 int data_len)
4917{
4918 int ret = 0;
4919
4920 vos_ssr_protect(__func__);
4921 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
4922 vos_ssr_unprotect(__func__);
4923
4924 return ret;
4925}
4926
4927static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304928 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304929 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304930 int data_len)
4931{
4932 u8 peer[6] = {0};
4933 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304934 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4935 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4936 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304937 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304938 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304939
4940 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304941
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304942 if (!dev) {
4943 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4944 return -EINVAL;
4945 }
4946
4947 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4948 if (!pAdapter) {
4949 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
4950 return -EINVAL;
4951 }
4952
Atul Mittal115287b2014-07-08 13:26:33 +05304953 status = wlan_hdd_validate_context(pHddCtx);
4954 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304955 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304956 return -EINVAL;
4957 }
4958 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304959 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304960 return -ENOTSUPP;
4961 }
4962 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4963 data, data_len,
4964 wlan_hdd_tdls_config_disable_policy)) {
4965 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4966 return -EINVAL;
4967 }
4968 /* Parse and fetch mac address */
4969 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4970 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4971 return -EINVAL;
4972 }
4973
4974 memcpy(peer, nla_data(
4975 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4976 sizeof(peer));
4977 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4978
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304979 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
4980
4981 EXIT();
4982 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304983}
4984
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304985static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4986 struct wireless_dev *wdev,
4987 const void *data,
4988 int data_len)
4989{
4990 int ret = 0;
4991
4992 vos_ssr_protect(__func__);
4993 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
4994 vos_ssr_unprotect(__func__);
4995
4996 return ret;
4997}
4998
Dasari Srinivas7875a302014-09-26 17:50:57 +05304999static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305000__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305001 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305002 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305003{
5004 struct net_device *dev = wdev->netdev;
5005 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5006 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5007 struct sk_buff *skb = NULL;
5008 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305009 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305010
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305011 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305012
5013 ret = wlan_hdd_validate_context(pHddCtx);
5014 if (0 != ret)
5015 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305016 return ret;
5017 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305018 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5019 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5020 fset |= WIFI_FEATURE_INFRA;
5021 }
5022
5023 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5024 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5025 fset |= WIFI_FEATURE_INFRA_5G;
5026 }
5027
5028#ifdef WLAN_FEATURE_P2P
5029 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5030 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5031 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5032 fset |= WIFI_FEATURE_P2P;
5033 }
5034#endif
5035
5036 /* Soft-AP is supported currently by default */
5037 fset |= WIFI_FEATURE_SOFT_AP;
5038
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305039 /* HOTSPOT is a supplicant feature, enable it by default */
5040 fset |= WIFI_FEATURE_HOTSPOT;
5041
Dasari Srinivas7875a302014-09-26 17:50:57 +05305042#ifdef WLAN_FEATURE_EXTSCAN
5043 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
5044 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
5045 hddLog(LOG1, FL("EXTScan is supported by firmware"));
5046 fset |= WIFI_FEATURE_EXTSCAN;
5047 }
5048#endif
5049
Dasari Srinivas7875a302014-09-26 17:50:57 +05305050 if (sme_IsFeatureSupportedByFW(NAN)) {
5051 hddLog(LOG1, FL("NAN is supported by firmware"));
5052 fset |= WIFI_FEATURE_NAN;
5053 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305054
5055 /* D2D RTT is not supported currently by default */
5056 if (sme_IsFeatureSupportedByFW(RTT)) {
5057 hddLog(LOG1, FL("RTT is supported by firmware"));
5058 fset |= WIFI_FEATURE_D2AP_RTT;
5059 }
5060
5061#ifdef FEATURE_WLAN_BATCH_SCAN
5062 if (fset & WIFI_FEATURE_EXTSCAN) {
5063 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5064 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5065 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5066 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5067 fset |= WIFI_FEATURE_BATCH_SCAN;
5068 }
5069#endif
5070
5071#ifdef FEATURE_WLAN_SCAN_PNO
5072 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5073 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5074 hddLog(LOG1, FL("PNO is supported by firmware"));
5075 fset |= WIFI_FEATURE_PNO;
5076 }
5077#endif
5078
5079 /* STA+STA is supported currently by default */
5080 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5081
5082#ifdef FEATURE_WLAN_TDLS
5083 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5084 sme_IsFeatureSupportedByFW(TDLS)) {
5085 hddLog(LOG1, FL("TDLS is supported by firmware"));
5086 fset |= WIFI_FEATURE_TDLS;
5087 }
5088
5089 /* TDLS_OFFCHANNEL is not supported currently by default */
5090#endif
5091
5092#ifdef WLAN_AP_STA_CONCURRENCY
5093 /* AP+STA concurrency is supported currently by default */
5094 fset |= WIFI_FEATURE_AP_STA;
5095#endif
5096
5097 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5098 NLMSG_HDRLEN);
5099
5100 if (!skb) {
5101 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5102 return -EINVAL;
5103 }
5104 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5105
5106 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5107 hddLog(LOGE, FL("nla put fail"));
5108 goto nla_put_failure;
5109 }
5110
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305111 ret = cfg80211_vendor_cmd_reply(skb);
5112 EXIT();
5113 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305114
5115nla_put_failure:
5116 kfree_skb(skb);
5117 return -EINVAL;
5118}
5119
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305120static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305121wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5122 struct wireless_dev *wdev,
5123 const void *data, int data_len)
5124{
5125 int ret = 0;
5126
5127 vos_ssr_protect(__func__);
5128 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5129 vos_ssr_unprotect(__func__);
5130
5131 return ret;
5132}
5133
5134static int
5135__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305136 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305137 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305138{
5139 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5140 uint8_t i, feature_sets, max_feature_sets;
5141 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5142 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305143 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5144 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305145
5146 ENTER();
5147
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305148 ret = wlan_hdd_validate_context(pHddCtx);
5149 if (0 != ret)
5150 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305151 return ret;
5152 }
5153
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305154 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5155 data, data_len, NULL)) {
5156 hddLog(LOGE, FL("Invalid ATTR"));
5157 return -EINVAL;
5158 }
5159
5160 /* Parse and fetch max feature set */
5161 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5162 hddLog(LOGE, FL("Attr max feature set size failed"));
5163 return -EINVAL;
5164 }
5165 max_feature_sets = nla_get_u32(
5166 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5167 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5168
5169 /* Fill feature combination matrix */
5170 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305171 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5172 WIFI_FEATURE_P2P;
5173
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305174 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5175 WIFI_FEATURE_SOFT_AP;
5176
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305177 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5178 WIFI_FEATURE_SOFT_AP;
5179
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305180 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5181 WIFI_FEATURE_SOFT_AP |
5182 WIFI_FEATURE_P2P;
5183
5184 /* Add more feature combinations here */
5185
5186 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5187 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5188 hddLog(LOG1, "Feature set matrix");
5189 for (i = 0; i < feature_sets; i++)
5190 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5191
5192 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5193 sizeof(u32) * feature_sets +
5194 NLMSG_HDRLEN);
5195
5196 if (reply_skb) {
5197 if (nla_put_u32(reply_skb,
5198 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5199 feature_sets) ||
5200 nla_put(reply_skb,
5201 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5202 sizeof(u32) * feature_sets, feature_set_matrix)) {
5203 hddLog(LOGE, FL("nla put fail"));
5204 kfree_skb(reply_skb);
5205 return -EINVAL;
5206 }
5207
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305208 ret = cfg80211_vendor_cmd_reply(reply_skb);
5209 EXIT();
5210 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305211 }
5212 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5213 return -ENOMEM;
5214
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305215}
5216
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305217static int
5218wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5219 struct wireless_dev *wdev,
5220 const void *data, int data_len)
5221{
5222 int ret = 0;
5223
5224 vos_ssr_protect(__func__);
5225 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5226 data_len);
5227 vos_ssr_unprotect(__func__);
5228
5229 return ret;
5230}
5231
Agarwal Ashish738843c2014-09-25 12:27:56 +05305232static const struct nla_policy
5233wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5234 +1] =
5235{
5236 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5237};
5238
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305239static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305240 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305241 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305242 int data_len)
5243{
5244 struct net_device *dev = wdev->netdev;
5245 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5246 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5247 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5248 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5249 eHalStatus status;
5250 u32 dfsFlag = 0;
5251
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305252 ENTER();
5253
Agarwal Ashish738843c2014-09-25 12:27:56 +05305254 status = wlan_hdd_validate_context(pHddCtx);
5255 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305256 return -EINVAL;
5257 }
5258 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5259 data, data_len,
5260 wlan_hdd_set_no_dfs_flag_config_policy)) {
5261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5262 return -EINVAL;
5263 }
5264
5265 /* Parse and fetch required bandwidth kbps */
5266 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5267 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5268 return -EINVAL;
5269 }
5270
5271 dfsFlag = nla_get_u32(
5272 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5273 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5274 dfsFlag);
5275
5276 pHddCtx->disable_dfs_flag = dfsFlag;
5277
5278 sme_disable_dfs_channel(hHal, dfsFlag);
5279 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305280
5281 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305282 return 0;
5283}
Atul Mittal115287b2014-07-08 13:26:33 +05305284
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305285static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
5286 struct wireless_dev *wdev,
5287 const void *data,
5288 int data_len)
5289{
5290 int ret = 0;
5291
5292 vos_ssr_protect(__func__);
5293 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
5294 vos_ssr_unprotect(__func__);
5295
5296 return ret;
5297
5298}
5299
Mukul Sharma2a271632014-10-13 14:59:01 +05305300const struct
5301nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
5302{
5303 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
5304 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
5305};
5306
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305307static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05305308 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05305309{
5310
5311 u8 bssid[6] = {0};
5312 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5313 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5314 eHalStatus status = eHAL_STATUS_SUCCESS;
5315 v_U32_t isFwrRoamEnabled = FALSE;
5316 int ret;
5317
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305318 ENTER();
5319
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305320 ret = wlan_hdd_validate_context(pHddCtx);
5321 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305322 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05305323 }
5324
5325 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
5326 data, data_len,
5327 qca_wlan_vendor_attr);
5328 if (ret){
5329 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5330 return -EINVAL;
5331 }
5332
5333 /* Parse and fetch Enable flag */
5334 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
5335 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
5336 return -EINVAL;
5337 }
5338
5339 isFwrRoamEnabled = nla_get_u32(
5340 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5341
5342 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5343
5344 /* Parse and fetch bssid */
5345 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5346 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5347 return -EINVAL;
5348 }
5349
5350 memcpy(bssid, nla_data(
5351 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
5352 sizeof(bssid));
5353 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
5354
5355 //Update roaming
5356 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305357 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05305358 return status;
5359}
5360
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305361static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
5362 struct wireless_dev *wdev, const void *data, int data_len)
5363{
5364 int ret = 0;
5365
5366 vos_ssr_protect(__func__);
5367 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
5368 vos_ssr_unprotect(__func__);
5369
5370 return ret;
5371}
5372
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305373/**
5374 * __wlan_hdd_cfg80211_setband() - set band
5375 * @wiphy: Pointer to wireless phy
5376 * @wdev: Pointer to wireless device
5377 * @data: Pointer to data
5378 * @data_len: Data length
5379 *
5380 * Return: 0 on success, negative errno on failure
5381 */
5382static int
5383__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
5384 struct wireless_dev *wdev,
5385 const void *data,
5386 int data_len)
5387{
5388 struct net_device *dev = wdev->netdev;
5389 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5390 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5391 int ret;
5392 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
5393 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
5394
5395 ENTER();
5396
5397 ret = wlan_hdd_validate_context(hdd_ctx);
5398 if (0 != ret) {
5399 hddLog(LOGE, FL("HDD context is not valid"));
5400 return ret;
5401 }
5402
5403 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
5404 policy)) {
5405 hddLog(LOGE, FL("Invalid ATTR"));
5406 return -EINVAL;
5407 }
5408
5409 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
5410 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
5411 return -EINVAL;
5412 }
5413
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05305414 hdd_ctx->isSetBandByNL = TRUE;
5415 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305416 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05305417 hdd_ctx->isSetBandByNL = FALSE;
5418
5419 EXIT();
5420 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305421}
5422
5423/**
5424 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
5425 * @wiphy: wiphy structure pointer
5426 * @wdev: Wireless device structure pointer
5427 * @data: Pointer to the data received
5428 * @data_len: Length of @data
5429 *
5430 * Return: 0 on success; errno on failure
5431 */
5432static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
5433 struct wireless_dev *wdev,
5434 const void *data,
5435 int data_len)
5436{
5437 int ret = 0;
5438
5439 vos_ssr_protect(__func__);
5440 ret = __wlan_hdd_cfg80211_setband(wiphy,
5441 wdev, data, data_len);
5442 vos_ssr_unprotect(__func__);
5443
5444 return ret;
5445}
5446
Sunil Duttc69bccb2014-05-26 21:30:20 +05305447const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
5448{
Mukul Sharma2a271632014-10-13 14:59:01 +05305449 {
5450 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5451 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
5452 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5453 WIPHY_VENDOR_CMD_NEED_NETDEV |
5454 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305455 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05305456 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05305457
5458 {
5459 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5460 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
5461 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5462 WIPHY_VENDOR_CMD_NEED_NETDEV |
5463 WIPHY_VENDOR_CMD_NEED_RUNNING,
5464 .doit = wlan_hdd_cfg80211_nan_request
5465 },
5466
Sunil Duttc69bccb2014-05-26 21:30:20 +05305467#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5468 {
5469 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5470 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
5471 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5472 WIPHY_VENDOR_CMD_NEED_NETDEV |
5473 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305474 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05305475 },
5476
5477 {
5478 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5479 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
5480 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5481 WIPHY_VENDOR_CMD_NEED_NETDEV |
5482 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305483 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05305484 },
5485
5486 {
5487 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5488 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
5489 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5490 WIPHY_VENDOR_CMD_NEED_NETDEV |
5491 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305492 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05305493 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305494#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305495#ifdef WLAN_FEATURE_EXTSCAN
5496 {
5497 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5498 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
5499 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5500 WIPHY_VENDOR_CMD_NEED_NETDEV |
5501 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305502 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05305503 },
5504 {
5505 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5506 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
5507 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5508 WIPHY_VENDOR_CMD_NEED_NETDEV |
5509 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305510 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05305511 },
5512 {
5513 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5514 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
5515 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5516 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305517 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05305518 },
5519 {
5520 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5521 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
5522 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5523 WIPHY_VENDOR_CMD_NEED_NETDEV |
5524 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305525 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05305526 },
5527 {
5528 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5529 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
5530 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5531 WIPHY_VENDOR_CMD_NEED_NETDEV |
5532 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305533 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05305534 },
5535 {
5536 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5537 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
5538 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5539 WIPHY_VENDOR_CMD_NEED_NETDEV |
5540 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305541 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305542 },
5543 {
5544 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5545 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
5546 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5547 WIPHY_VENDOR_CMD_NEED_NETDEV |
5548 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305549 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305550 },
5551 {
5552 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5553 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
5554 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5555 WIPHY_VENDOR_CMD_NEED_NETDEV |
5556 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305557 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305558 },
5559 {
5560 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5561 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
5562 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5563 WIPHY_VENDOR_CMD_NEED_NETDEV |
5564 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305565 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305566 },
5567#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305568/*EXT TDLS*/
5569 {
5570 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5571 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
5572 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5573 WIPHY_VENDOR_CMD_NEED_NETDEV |
5574 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305575 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05305576 },
5577 {
5578 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5579 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
5580 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5581 WIPHY_VENDOR_CMD_NEED_NETDEV |
5582 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305583 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05305584 },
5585 {
5586 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5587 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
5588 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5589 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305590 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05305591 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05305592 {
5593 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5594 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
5595 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5596 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305597 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05305598 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05305599 {
5600 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5601 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
5602 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5603 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305604 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05305605 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305606 {
5607 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5608 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
5609 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5610 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305611 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305612 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305613 {
5614 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5615 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
5616 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5617 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305618 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305619 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305620 {
5621 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5622 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
5623 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5624 WIPHY_VENDOR_CMD_NEED_NETDEV |
5625 WIPHY_VENDOR_CMD_NEED_RUNNING,
5626 .doit = wlan_hdd_cfg80211_setband
5627 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05305628};
5629
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005630/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05305631static const
5632struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005633{
5634#ifdef FEATURE_WLAN_CH_AVOID
5635 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05305636 .vendor_id = QCA_NL80211_VENDOR_ID,
5637 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005638 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305639#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
5640#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5641 {
5642 /* Index = 1*/
5643 .vendor_id = QCA_NL80211_VENDOR_ID,
5644 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
5645 },
5646 {
5647 /* Index = 2*/
5648 .vendor_id = QCA_NL80211_VENDOR_ID,
5649 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
5650 },
5651 {
5652 /* Index = 3*/
5653 .vendor_id = QCA_NL80211_VENDOR_ID,
5654 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
5655 },
5656 {
5657 /* Index = 4*/
5658 .vendor_id = QCA_NL80211_VENDOR_ID,
5659 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
5660 },
5661 {
5662 /* Index = 5*/
5663 .vendor_id = QCA_NL80211_VENDOR_ID,
5664 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
5665 },
5666 {
5667 /* Index = 6*/
5668 .vendor_id = QCA_NL80211_VENDOR_ID,
5669 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
5670 },
5671#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305672#ifdef WLAN_FEATURE_EXTSCAN
5673 {
5674 .vendor_id = QCA_NL80211_VENDOR_ID,
5675 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
5676 },
5677 {
5678 .vendor_id = QCA_NL80211_VENDOR_ID,
5679 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
5680 },
5681 {
5682 .vendor_id = QCA_NL80211_VENDOR_ID,
5683 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
5684 },
5685 {
5686 .vendor_id = QCA_NL80211_VENDOR_ID,
5687 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
5688 },
5689 {
5690 .vendor_id = QCA_NL80211_VENDOR_ID,
5691 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
5692 },
5693 {
5694 .vendor_id = QCA_NL80211_VENDOR_ID,
5695 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
5696 },
5697 {
5698 .vendor_id = QCA_NL80211_VENDOR_ID,
5699 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
5700 },
5701 {
5702 .vendor_id = QCA_NL80211_VENDOR_ID,
5703 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
5704 },
5705 {
5706 .vendor_id = QCA_NL80211_VENDOR_ID,
5707 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
5708 },
5709 {
5710 .vendor_id = QCA_NL80211_VENDOR_ID,
5711 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
5712 },
5713 {
5714 .vendor_id = QCA_NL80211_VENDOR_ID,
5715 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
5716 },
5717 {
5718 .vendor_id = QCA_NL80211_VENDOR_ID,
5719 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
5720 },
5721 {
5722 .vendor_id = QCA_NL80211_VENDOR_ID,
5723 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
5724 },
5725#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305726/*EXT TDLS*/
5727 {
5728 .vendor_id = QCA_NL80211_VENDOR_ID,
5729 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
5730 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05305731
5732 {
5733 .vendor_id = QCA_NL80211_VENDOR_ID,
5734 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
5735 },
5736
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005737};
5738
Jeff Johnson295189b2012-06-20 16:38:30 -07005739/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305740 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305741 * This function is called by hdd_wlan_startup()
5742 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305743 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07005744 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305745struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07005746{
5747 struct wiphy *wiphy;
5748 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305749 /*
5750 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07005751 */
5752 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
5753
5754 if (!wiphy)
5755 {
5756 /* Print error and jump into err label and free the memory */
5757 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
5758 return NULL;
5759 }
5760
Sunil Duttc69bccb2014-05-26 21:30:20 +05305761
Jeff Johnson295189b2012-06-20 16:38:30 -07005762 return wiphy;
5763}
5764
5765/*
5766 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305767 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07005768 * private ioctl to change the band value
5769 */
5770int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
5771{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305772 int i, j;
5773 eNVChannelEnabledType channelEnabledState;
5774
Jeff Johnsone7245742012-09-05 17:12:55 -07005775 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305776
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305777 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005778 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305779
5780 if (NULL == wiphy->bands[i])
5781 {
5782 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5783 __func__, i);
5784 continue;
5785 }
5786
5787 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5788 {
5789 struct ieee80211_supported_band *band = wiphy->bands[i];
5790
5791 channelEnabledState = vos_nv_getChannelEnabledState(
5792 band->channels[j].hw_value);
5793
5794 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
5795 {
Abhishek Singh678227a2014-11-04 10:52:38 +05305796 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305797 continue;
5798 }
5799 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
5800 {
5801 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5802 continue;
5803 }
5804
5805 if (NV_CHANNEL_DISABLE == channelEnabledState ||
5806 NV_CHANNEL_INVALID == channelEnabledState)
5807 {
5808 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5809 }
5810 else if (NV_CHANNEL_DFS == channelEnabledState)
5811 {
5812 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5813 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
5814 }
5815 else
5816 {
5817 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
5818 |IEEE80211_CHAN_RADAR);
5819 }
5820 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005821 }
5822 return 0;
5823}
5824/*
5825 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305826 * This function is called by hdd_wlan_startup()
5827 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07005828 * This function is used to initialize and register wiphy structure.
5829 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305830int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005831 struct wiphy *wiphy,
5832 hdd_config_t *pCfg
5833 )
5834{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305835 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305836 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5837
Jeff Johnsone7245742012-09-05 17:12:55 -07005838 ENTER();
5839
Jeff Johnson295189b2012-06-20 16:38:30 -07005840 /* Now bind the underlying wlan device with wiphy */
5841 set_wiphy_dev(wiphy, dev);
5842
5843 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005844
Kiet Lam6c583332013-10-14 05:37:09 +05305845#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07005846 /* the flag for the other case would be initialzed in
5847 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07005848 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05305849#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005850
Amar Singhalfddc28c2013-09-05 13:03:40 -07005851 /* This will disable updating of NL channels from passive to
5852 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05305853#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
5854 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
5855#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07005856 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05305857#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07005858
Amar Singhala49cbc52013-10-08 18:37:44 -07005859
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005860#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07005861 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
5862 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
5863 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07005864 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05305865#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
5866 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
5867#else
5868 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
5869#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005870#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005871
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005872#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005873 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08005874#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005875 || pCfg->isFastRoamIniFeatureEnabled
5876#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005877#ifdef FEATURE_WLAN_ESE
5878 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005879#endif
5880 )
5881 {
5882 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5883 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08005884#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005885#ifdef FEATURE_WLAN_TDLS
5886 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
5887 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
5888#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305889#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05305890 if (pCfg->configPNOScanSupport)
5891 {
5892 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5893 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
5894 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
5895 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
5896 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305897#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005898
Abhishek Singh10d85972015-04-17 10:27:23 +05305899#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5900 wiphy->features |= NL80211_FEATURE_HT_IBSS;
5901#endif
5902
Amar Singhalfddc28c2013-09-05 13:03:40 -07005903#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005904 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
5905 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07005906 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005907 driver need to determine what to do with both
5908 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07005909
5910 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07005911#else
5912 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005913#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005914
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305915 wiphy->max_scan_ssids = MAX_SCAN_SSID;
5916
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05305917 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07005918
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305919 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
5920
Jeff Johnson295189b2012-06-20 16:38:30 -07005921 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05305922 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
5923 | BIT(NL80211_IFTYPE_ADHOC)
5924 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5925 | BIT(NL80211_IFTYPE_P2P_GO)
5926 | BIT(NL80211_IFTYPE_AP);
5927
5928 if (VOS_MONITOR_MODE == hdd_get_conparam())
5929 {
5930 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
5931 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005932
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305933 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005934 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305935#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5936 if( pCfg->enableMCC )
5937 {
5938 /* Currently, supports up to two channels */
5939 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005940
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305941 if( !pCfg->allowMCCGODiffBI )
5942 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005943
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305944 }
5945 wiphy->iface_combinations = &wlan_hdd_iface_combination;
5946 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005947#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305948 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005949
Jeff Johnson295189b2012-06-20 16:38:30 -07005950 /* Before registering we need to update the ht capabilitied based
5951 * on ini values*/
5952 if( !pCfg->ShortGI20MhzEnable )
5953 {
5954 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5955 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5956 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5957 }
5958
5959 if( !pCfg->ShortGI40MhzEnable )
5960 {
5961 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
5962 }
5963
5964 if( !pCfg->nChannelBondingMode5GHz )
5965 {
5966 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5967 }
5968
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305969 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305970 if (true == hdd_is_5g_supported(pHddCtx))
5971 {
5972 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
5973 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305974
5975 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
5976 {
5977
5978 if (NULL == wiphy->bands[i])
5979 {
5980 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5981 __func__, i);
5982 continue;
5983 }
5984
5985 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5986 {
5987 struct ieee80211_supported_band *band = wiphy->bands[i];
5988
5989 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
5990 {
5991 // Enable social channels for P2P
5992 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
5993 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5994 else
5995 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5996 continue;
5997 }
5998 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
5999 {
6000 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6001 continue;
6002 }
6003 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006004 }
6005 /*Initialise the supported cipher suite details*/
6006 wiphy->cipher_suites = hdd_cipher_suites;
6007 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
6008
6009 /*signal strength in mBm (100*dBm) */
6010 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
6011
6012#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05306013 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07006014#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006015
Sunil Duttc69bccb2014-05-26 21:30:20 +05306016 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
6017 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006018 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
6019 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
6020
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306021 EXIT();
6022 return 0;
6023}
6024
6025/* In this function we are registering wiphy. */
6026int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
6027{
6028 ENTER();
6029 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006030 if (0 > wiphy_register(wiphy))
6031 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306032 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07006033 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
6034 return -EIO;
6035 }
6036
6037 EXIT();
6038 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306039}
Jeff Johnson295189b2012-06-20 16:38:30 -07006040
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306041/* In this function we are updating channel list when,
6042 regulatory domain is FCC and country code is US.
6043 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
6044 As per FCC smart phone is not a indoor device.
6045 GO should not opeate on indoor channels */
6046void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
6047{
6048 int j;
6049 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6050 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
6051 //Default counrtycode from NV at the time of wiphy initialization.
6052 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
6053 &defaultCountryCode[0]))
6054 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006055 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306056 }
6057 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
6058 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306059 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
6060 {
6061 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
6062 return;
6063 }
6064 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
6065 {
6066 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
6067 // Mark UNII -1 band channel as passive
6068 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
6069 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
6070 }
6071 }
6072}
6073
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306074/* This function registers for all frame which supplicant is interested in */
6075void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006076{
Jeff Johnson295189b2012-06-20 16:38:30 -07006077 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6078 /* Register for all P2P action, public action etc frames */
6079 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6080
Jeff Johnsone7245742012-09-05 17:12:55 -07006081 ENTER();
6082
Jeff Johnson295189b2012-06-20 16:38:30 -07006083 /* Right now we are registering these frame when driver is getting
6084 initialized. Once we will move to 2.6.37 kernel, in which we have
6085 frame register ops, we will move this code as a part of that */
6086 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306087 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006088 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6089
6090 /* GAS Initial Response */
6091 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6092 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306093
Jeff Johnson295189b2012-06-20 16:38:30 -07006094 /* GAS Comeback Request */
6095 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6096 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6097
6098 /* GAS Comeback Response */
6099 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6100 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6101
6102 /* P2P Public Action */
6103 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306104 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006105 P2P_PUBLIC_ACTION_FRAME_SIZE );
6106
6107 /* P2P Action */
6108 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6109 (v_U8_t*)P2P_ACTION_FRAME,
6110 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07006111
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05306112 /* WNM BSS Transition Request frame */
6113 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6114 (v_U8_t*)WNM_BSS_ACTION_FRAME,
6115 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006116
6117 /* WNM-Notification */
6118 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6119 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6120 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006121}
6122
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306123void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006124{
Jeff Johnson295189b2012-06-20 16:38:30 -07006125 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6126 /* Register for all P2P action, public action etc frames */
6127 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6128
Jeff Johnsone7245742012-09-05 17:12:55 -07006129 ENTER();
6130
Jeff Johnson295189b2012-06-20 16:38:30 -07006131 /* Right now we are registering these frame when driver is getting
6132 initialized. Once we will move to 2.6.37 kernel, in which we have
6133 frame register ops, we will move this code as a part of that */
6134 /* GAS Initial Request */
6135
6136 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6137 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6138
6139 /* GAS Initial Response */
6140 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6141 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306142
Jeff Johnson295189b2012-06-20 16:38:30 -07006143 /* GAS Comeback Request */
6144 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6145 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6146
6147 /* GAS Comeback Response */
6148 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6149 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6150
6151 /* P2P Public Action */
6152 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306153 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006154 P2P_PUBLIC_ACTION_FRAME_SIZE );
6155
6156 /* P2P Action */
6157 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6158 (v_U8_t*)P2P_ACTION_FRAME,
6159 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006160 /* WNM-Notification */
6161 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6162 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6163 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006164}
6165
6166#ifdef FEATURE_WLAN_WAPI
6167void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05306168 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006169{
6170 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6171 tCsrRoamSetKey setKey;
6172 v_BOOL_t isConnected = TRUE;
6173 int status = 0;
6174 v_U32_t roamId= 0xFF;
6175 tANI_U8 *pKeyPtr = NULL;
6176 int n = 0;
6177
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306178 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
6179 __func__, hdd_device_modetoString(pAdapter->device_mode),
6180 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006181
Gopichand Nakkalae7480202013-02-11 15:24:22 +05306182 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006183 setKey.keyId = key_index; // Store Key ID
6184 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
6185 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
6186 setKey.paeRole = 0 ; // the PAE role
6187 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
6188 {
6189 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
6190 }
6191 else
6192 {
6193 isConnected = hdd_connIsConnected(pHddStaCtx);
6194 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
6195 }
6196 setKey.keyLength = key_Len;
6197 pKeyPtr = setKey.Key;
6198 memcpy( pKeyPtr, key, key_Len);
6199
Arif Hussain6d2a3322013-11-17 19:50:10 -08006200 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07006201 __func__, key_Len);
6202 for (n = 0 ; n < key_Len; n++)
6203 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
6204 __func__,n,setKey.Key[n]);
6205
6206 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
6207 if ( isConnected )
6208 {
6209 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
6210 pAdapter->sessionId, &setKey, &roamId );
6211 }
6212 if ( status != 0 )
6213 {
6214 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6215 "[%4d] sme_RoamSetKey returned ERROR status= %d",
6216 __LINE__, status );
6217 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
6218 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05306219 /* Need to clear any trace of key value in the memory.
6220 * Thus zero out the memory even though it is local
6221 * variable.
6222 */
6223 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006224}
6225#endif /* FEATURE_WLAN_WAPI*/
6226
6227#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306228int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006229 beacon_data_t **ppBeacon,
6230 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006231#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306232int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006233 beacon_data_t **ppBeacon,
6234 struct cfg80211_beacon_data *params,
6235 int dtim_period)
6236#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306237{
Jeff Johnson295189b2012-06-20 16:38:30 -07006238 int size;
6239 beacon_data_t *beacon = NULL;
6240 beacon_data_t *old = NULL;
6241 int head_len,tail_len;
6242
Jeff Johnsone7245742012-09-05 17:12:55 -07006243 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006244 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306245 {
6246 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6247 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006248 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306249 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006250
6251 old = pAdapter->sessionCtx.ap.beacon;
6252
6253 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306254 {
6255 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6256 FL("session(%d) old and new heads points to NULL"),
6257 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006258 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306259 }
6260
6261 if (params->tail && !params->tail_len)
6262 {
6263 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6264 FL("tail_len is zero but tail is not NULL"));
6265 return -EINVAL;
6266 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006267
Jeff Johnson295189b2012-06-20 16:38:30 -07006268#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
6269 /* Kernel 3.0 is not updating dtim_period for set beacon */
6270 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306271 {
6272 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6273 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006274 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306275 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006276#endif
6277
6278 if(params->head)
6279 head_len = params->head_len;
6280 else
6281 head_len = old->head_len;
6282
6283 if(params->tail || !old)
6284 tail_len = params->tail_len;
6285 else
6286 tail_len = old->tail_len;
6287
6288 size = sizeof(beacon_data_t) + head_len + tail_len;
6289
6290 beacon = kzalloc(size, GFP_KERNEL);
6291
6292 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306293 {
6294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6295 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006296 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306297 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006298
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006299#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006300 if(params->dtim_period || !old )
6301 beacon->dtim_period = params->dtim_period;
6302 else
6303 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006304#else
6305 if(dtim_period || !old )
6306 beacon->dtim_period = dtim_period;
6307 else
6308 beacon->dtim_period = old->dtim_period;
6309#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306310
Jeff Johnson295189b2012-06-20 16:38:30 -07006311 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6312 beacon->tail = beacon->head + head_len;
6313 beacon->head_len = head_len;
6314 beacon->tail_len = tail_len;
6315
6316 if(params->head) {
6317 memcpy (beacon->head,params->head,beacon->head_len);
6318 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306319 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07006320 if(old)
6321 memcpy (beacon->head,old->head,beacon->head_len);
6322 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306323
Jeff Johnson295189b2012-06-20 16:38:30 -07006324 if(params->tail) {
6325 memcpy (beacon->tail,params->tail,beacon->tail_len);
6326 }
6327 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306328 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07006329 memcpy (beacon->tail,old->tail,beacon->tail_len);
6330 }
6331
6332 *ppBeacon = beacon;
6333
6334 kfree(old);
6335
6336 return 0;
6337
6338}
Jeff Johnson295189b2012-06-20 16:38:30 -07006339
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05306340v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
6341#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6342 const v_U8_t *pIes,
6343#else
6344 v_U8_t *pIes,
6345#endif
6346 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006347{
6348 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05306349 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07006350 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306351
Jeff Johnson295189b2012-06-20 16:38:30 -07006352 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306353 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006354 elem_id = ptr[0];
6355 elem_len = ptr[1];
6356 left -= 2;
6357 if(elem_len > left)
6358 {
6359 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006360 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006361 eid,elem_len,left);
6362 return NULL;
6363 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306364 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006365 {
6366 return ptr;
6367 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306368
Jeff Johnson295189b2012-06-20 16:38:30 -07006369 left -= elem_len;
6370 ptr += (elem_len + 2);
6371 }
6372 return NULL;
6373}
6374
Jeff Johnson295189b2012-06-20 16:38:30 -07006375/* Check if rate is 11g rate or not */
6376static int wlan_hdd_rate_is_11g(u8 rate)
6377{
Sanjay Devnani28322e22013-06-21 16:13:40 -07006378 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006379 u8 i;
6380 for (i = 0; i < 8; i++)
6381 {
6382 if(rate == gRateArray[i])
6383 return TRUE;
6384 }
6385 return FALSE;
6386}
6387
6388/* Check for 11g rate and set proper 11g only mode */
6389static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
6390 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
6391{
6392 u8 i, num_rates = pIe[0];
6393
6394 pIe += 1;
6395 for ( i = 0; i < num_rates; i++)
6396 {
6397 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
6398 {
6399 /* If rate set have 11g rate than change the mode to 11G */
6400 *pSapHw_mode = eSAP_DOT11_MODE_11g;
6401 if (pIe[i] & BASIC_RATE_MASK)
6402 {
6403 /* If we have 11g rate as basic rate, it means mode
6404 is 11g only mode.
6405 */
6406 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
6407 *pCheckRatesfor11g = FALSE;
6408 }
6409 }
6410 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
6411 {
6412 *require_ht = TRUE;
6413 }
6414 }
6415 return;
6416}
6417
6418static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
6419{
6420 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6421 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6422 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6423 u8 checkRatesfor11g = TRUE;
6424 u8 require_ht = FALSE;
6425 u8 *pIe=NULL;
6426
6427 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
6428
6429 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
6430 pBeacon->head_len, WLAN_EID_SUPP_RATES);
6431 if (pIe != NULL)
6432 {
6433 pIe += 1;
6434 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6435 &pConfig->SapHw_mode);
6436 }
6437
6438 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6439 WLAN_EID_EXT_SUPP_RATES);
6440 if (pIe != NULL)
6441 {
6442
6443 pIe += 1;
6444 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6445 &pConfig->SapHw_mode);
6446 }
6447
6448 if( pConfig->channel > 14 )
6449 {
6450 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
6451 }
6452
6453 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6454 WLAN_EID_HT_CAPABILITY);
6455
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306456 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006457 {
6458 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
6459 if(require_ht)
6460 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
6461 }
6462}
6463
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306464static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
6465 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
6466{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006467 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306468 v_U8_t *pIe = NULL;
6469 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6470
6471 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
6472 pBeacon->tail, pBeacon->tail_len);
6473
6474 if (pIe)
6475 {
6476 ielen = pIe[1] + 2;
6477 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6478 {
6479 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
6480 }
6481 else
6482 {
6483 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
6484 return -EINVAL;
6485 }
6486 *total_ielen += ielen;
6487 }
6488 return 0;
6489}
6490
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006491static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
6492 v_U8_t *genie, v_U8_t *total_ielen)
6493{
6494 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6495 int left = pBeacon->tail_len;
6496 v_U8_t *ptr = pBeacon->tail;
6497 v_U8_t elem_id, elem_len;
6498 v_U16_t ielen = 0;
6499
6500 if ( NULL == ptr || 0 == left )
6501 return;
6502
6503 while (left >= 2)
6504 {
6505 elem_id = ptr[0];
6506 elem_len = ptr[1];
6507 left -= 2;
6508 if (elem_len > left)
6509 {
6510 hddLog( VOS_TRACE_LEVEL_ERROR,
6511 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
6512 elem_id, elem_len, left);
6513 return;
6514 }
6515 if (IE_EID_VENDOR == elem_id)
6516 {
6517 /* skipping the VSIE's which we don't want to include or
6518 * it will be included by existing code
6519 */
6520 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
6521#ifdef WLAN_FEATURE_WFD
6522 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
6523#endif
6524 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6525 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6526 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
6527 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6528 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
6529 {
6530 ielen = ptr[1] + 2;
6531 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6532 {
6533 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
6534 *total_ielen += ielen;
6535 }
6536 else
6537 {
6538 hddLog( VOS_TRACE_LEVEL_ERROR,
6539 "IE Length is too big "
6540 "IEs eid=%d elem_len=%d total_ie_lent=%d",
6541 elem_id, elem_len, *total_ielen);
6542 }
6543 }
6544 }
6545
6546 left -= elem_len;
6547 ptr += (elem_len + 2);
6548 }
6549 return;
6550}
6551
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006552#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006553static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6554 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006555#else
6556static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6557 struct cfg80211_beacon_data *params)
6558#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006559{
6560 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306561 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006562 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07006563 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006564
6565 genie = vos_mem_malloc(MAX_GENIE_LEN);
6566
6567 if(genie == NULL) {
6568
6569 return -ENOMEM;
6570 }
6571
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306572 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6573 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006574 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306575 hddLog(LOGE,
6576 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306577 ret = -EINVAL;
6578 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006579 }
6580
6581#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306582 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6583 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
6584 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306585 hddLog(LOGE,
6586 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306587 ret = -EINVAL;
6588 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006589 }
6590#endif
6591
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306592 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6593 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006594 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306595 hddLog(LOGE,
6596 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306597 ret = -EINVAL;
6598 goto done;
6599 }
6600
6601 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
6602 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006603 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07006604 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006605
6606 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6607 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
6608 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
6609 {
6610 hddLog(LOGE,
6611 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006612 ret = -EINVAL;
6613 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006614 }
6615
6616 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6617 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6618 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6619 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6620 ==eHAL_STATUS_FAILURE)
6621 {
6622 hddLog(LOGE,
6623 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006624 ret = -EINVAL;
6625 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006626 }
6627
6628 // Added for ProResp IE
6629 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
6630 {
6631 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
6632 u8 probe_rsp_ie_len[3] = {0};
6633 u8 counter = 0;
6634 /* Check Probe Resp Length if it is greater then 255 then Store
6635 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
6636 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
6637 Store More then 255 bytes into One Variable.
6638 */
6639 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6640 {
6641 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6642 {
6643 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6644 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6645 }
6646 else
6647 {
6648 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6649 rem_probe_resp_ie_len = 0;
6650 }
6651 }
6652
6653 rem_probe_resp_ie_len = 0;
6654
6655 if (probe_rsp_ie_len[0] > 0)
6656 {
6657 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6658 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6659 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6660 probe_rsp_ie_len[0], NULL,
6661 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6662 {
6663 hddLog(LOGE,
6664 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006665 ret = -EINVAL;
6666 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006667 }
6668 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6669 }
6670
6671 if (probe_rsp_ie_len[1] > 0)
6672 {
6673 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6674 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6675 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6676 probe_rsp_ie_len[1], NULL,
6677 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6678 {
6679 hddLog(LOGE,
6680 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006681 ret = -EINVAL;
6682 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006683 }
6684 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6685 }
6686
6687 if (probe_rsp_ie_len[2] > 0)
6688 {
6689 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6690 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6691 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6692 probe_rsp_ie_len[2], NULL,
6693 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6694 {
6695 hddLog(LOGE,
6696 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006697 ret = -EINVAL;
6698 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006699 }
6700 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6701 }
6702
6703 if (probe_rsp_ie_len[1] == 0 )
6704 {
6705 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6706 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6707 eANI_BOOLEAN_FALSE) )
6708 {
6709 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006710 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006711 }
6712 }
6713
6714 if (probe_rsp_ie_len[2] == 0 )
6715 {
6716 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6717 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6718 eANI_BOOLEAN_FALSE) )
6719 {
6720 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006721 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006722 }
6723 }
6724
6725 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6726 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6727 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6728 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6729 == eHAL_STATUS_FAILURE)
6730 {
6731 hddLog(LOGE,
6732 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006733 ret = -EINVAL;
6734 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006735 }
6736 }
6737 else
6738 {
6739 // Reset WNI_CFG_PROBE_RSP Flags
6740 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
6741
6742 hddLog(VOS_TRACE_LEVEL_INFO,
6743 "%s: No Probe Response IE received in set beacon",
6744 __func__);
6745 }
6746
6747 // Added for AssocResp IE
6748 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
6749 {
6750 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6751 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
6752 params->assocresp_ies_len, NULL,
6753 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6754 {
6755 hddLog(LOGE,
6756 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006757 ret = -EINVAL;
6758 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006759 }
6760
6761 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6762 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
6763 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6764 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6765 == eHAL_STATUS_FAILURE)
6766 {
6767 hddLog(LOGE,
6768 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006769 ret = -EINVAL;
6770 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006771 }
6772 }
6773 else
6774 {
6775 hddLog(VOS_TRACE_LEVEL_INFO,
6776 "%s: No Assoc Response IE received in set beacon",
6777 __func__);
6778
6779 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6780 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6781 eANI_BOOLEAN_FALSE) )
6782 {
6783 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006784 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006785 }
6786 }
6787
Jeff Johnsone7245742012-09-05 17:12:55 -07006788done:
Jeff Johnson295189b2012-06-20 16:38:30 -07006789 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306790 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006791}
Jeff Johnson295189b2012-06-20 16:38:30 -07006792
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306793/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006794 * FUNCTION: wlan_hdd_validate_operation_channel
6795 * called by wlan_hdd_cfg80211_start_bss() and
6796 * wlan_hdd_cfg80211_set_channel()
6797 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306798 * channel list.
6799 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006800VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006801{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306802
Jeff Johnson295189b2012-06-20 16:38:30 -07006803 v_U32_t num_ch = 0;
6804 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6805 u32 indx = 0;
6806 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306807 v_U8_t fValidChannel = FALSE, count = 0;
6808 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306809
Jeff Johnson295189b2012-06-20 16:38:30 -07006810 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6811
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306812 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006813 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306814 /* Validate the channel */
6815 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006816 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306817 if ( channel == rfChannels[count].channelNum )
6818 {
6819 fValidChannel = TRUE;
6820 break;
6821 }
6822 }
6823 if (fValidChannel != TRUE)
6824 {
6825 hddLog(VOS_TRACE_LEVEL_ERROR,
6826 "%s: Invalid Channel [%d]", __func__, channel);
6827 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006828 }
6829 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306830 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006831 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306832 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6833 valid_ch, &num_ch))
6834 {
6835 hddLog(VOS_TRACE_LEVEL_ERROR,
6836 "%s: failed to get valid channel list", __func__);
6837 return VOS_STATUS_E_FAILURE;
6838 }
6839 for (indx = 0; indx < num_ch; indx++)
6840 {
6841 if (channel == valid_ch[indx])
6842 {
6843 break;
6844 }
6845 }
6846
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306847 if (indx >= num_ch)
6848 {
6849 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6850 {
6851 eCsrBand band;
6852 unsigned int freq;
6853
6854 sme_GetFreqBand(hHal, &band);
6855
6856 if (eCSR_BAND_5G == band)
6857 {
6858#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
6859 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
6860 {
6861 freq = ieee80211_channel_to_frequency(channel,
6862 IEEE80211_BAND_2GHZ);
6863 }
6864 else
6865 {
6866 freq = ieee80211_channel_to_frequency(channel,
6867 IEEE80211_BAND_5GHZ);
6868 }
6869#else
6870 freq = ieee80211_channel_to_frequency(channel);
6871#endif
6872 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
6873 return VOS_STATUS_SUCCESS;
6874 }
6875 }
6876
6877 hddLog(VOS_TRACE_LEVEL_ERROR,
6878 "%s: Invalid Channel [%d]", __func__, channel);
6879 return VOS_STATUS_E_FAILURE;
6880 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006881 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306882
Jeff Johnson295189b2012-06-20 16:38:30 -07006883 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306884
Jeff Johnson295189b2012-06-20 16:38:30 -07006885}
6886
Viral Modi3a32cc52013-02-08 11:14:52 -08006887/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306888 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08006889 * This function is used to set the channel number
6890 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306891static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08006892 struct ieee80211_channel *chan,
6893 enum nl80211_channel_type channel_type
6894 )
6895{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306896 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08006897 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07006898 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08006899 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306900 hdd_context_t *pHddCtx;
6901 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006902
6903 ENTER();
6904
6905 if( NULL == dev )
6906 {
6907 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006908 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006909 return -ENODEV;
6910 }
6911 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306912
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306913 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6914 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
6915 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08006916 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306917 "%s: device_mode = %s (%d) freq = %d", __func__,
6918 hdd_device_modetoString(pAdapter->device_mode),
6919 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306920
6921 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6922 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306923 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08006924 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306925 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006926 }
6927
6928 /*
6929 * Do freq to chan conversion
6930 * TODO: for 11a
6931 */
6932
6933 channel = ieee80211_frequency_to_channel(freq);
6934
6935 /* Check freq range */
6936 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6937 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
6938 {
6939 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006940 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08006941 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6942 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6943 return -EINVAL;
6944 }
6945
6946 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6947
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05306948 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6949 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08006950 {
6951 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
6952 {
6953 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006954 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08006955 return -EINVAL;
6956 }
6957 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6958 "%s: set channel to [%d] for device mode =%d",
6959 __func__, channel,pAdapter->device_mode);
6960 }
6961 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08006962 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08006963 )
6964 {
6965 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6966 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
6967 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6968
6969 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
6970 {
6971 /* Link is up then return cant set channel*/
6972 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006973 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006974 return -EINVAL;
6975 }
6976
6977 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6978 pHddStaCtx->conn_info.operationChannel = channel;
6979 pRoamProfile->ChannelInfo.ChannelList =
6980 &pHddStaCtx->conn_info.operationChannel;
6981 }
6982 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08006983 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08006984 )
6985 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306986 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6987 {
6988 if(VOS_STATUS_SUCCESS !=
6989 wlan_hdd_validate_operation_channel(pAdapter,channel))
6990 {
6991 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006992 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306993 return -EINVAL;
6994 }
6995 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6996 }
6997 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08006998 {
6999 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
7000
7001 /* If auto channel selection is configured as enable/ 1 then ignore
7002 channel set by supplicant
7003 */
7004 if ( cfg_param->apAutoChannelSelection )
7005 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307006 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
7007 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08007008 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307009 "%s: set channel to auto channel (0) for device mode =%s (%d)",
7010 __func__, hdd_device_modetoString(pAdapter->device_mode),
7011 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08007012 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307013 else
7014 {
7015 if(VOS_STATUS_SUCCESS !=
7016 wlan_hdd_validate_operation_channel(pAdapter,channel))
7017 {
7018 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007019 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307020 return -EINVAL;
7021 }
7022 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7023 }
Viral Modi3a32cc52013-02-08 11:14:52 -08007024 }
7025 }
7026 else
7027 {
7028 hddLog(VOS_TRACE_LEVEL_FATAL,
7029 "%s: Invalid device mode failed to set valid channel", __func__);
7030 return -EINVAL;
7031 }
7032 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307033 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007034}
7035
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307036static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
7037 struct net_device *dev,
7038 struct ieee80211_channel *chan,
7039 enum nl80211_channel_type channel_type
7040 )
7041{
7042 int ret;
7043
7044 vos_ssr_protect(__func__);
7045 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
7046 vos_ssr_unprotect(__func__);
7047
7048 return ret;
7049}
7050
Jeff Johnson295189b2012-06-20 16:38:30 -07007051#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7052static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7053 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007054#else
7055static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7056 struct cfg80211_beacon_data *params,
7057 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307058 enum nl80211_hidden_ssid hidden_ssid,
7059 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007060#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007061{
7062 tsap_Config_t *pConfig;
7063 beacon_data_t *pBeacon = NULL;
7064 struct ieee80211_mgmt *pMgmt_frame;
7065 v_U8_t *pIe=NULL;
7066 v_U16_t capab_info;
7067 eCsrAuthType RSNAuthType;
7068 eCsrEncryptionType RSNEncryptType;
7069 eCsrEncryptionType mcRSNEncryptType;
7070 int status = VOS_STATUS_SUCCESS;
7071 tpWLAN_SAPEventCB pSapEventCallback;
7072 hdd_hostapd_state_t *pHostapdState;
7073 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
7074 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307075 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007076 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307077 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07007078 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08007079 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05307080 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07007081 v_BOOL_t MFPCapable = VOS_FALSE;
7082 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307083 v_BOOL_t sapEnable11AC =
7084 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07007085 ENTER();
7086
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307087 iniConfig = pHddCtx->cfg_ini;
7088
Jeff Johnson295189b2012-06-20 16:38:30 -07007089 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
7090
7091 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7092
7093 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7094
7095 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
7096
7097 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
7098
7099 //channel is already set in the set_channel Call back
7100 //pConfig->channel = pCommitConfig->channel;
7101
7102 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307103 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07007104 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
7105
7106 pConfig->dtim_period = pBeacon->dtim_period;
7107
Arif Hussain6d2a3322013-11-17 19:50:10 -08007108 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07007109 pConfig->dtim_period);
7110
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08007111 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07007112 {
7113 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007114 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05307115 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
7116 {
7117 tANI_BOOLEAN restartNeeded;
7118 pConfig->ieee80211d = 1;
7119 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
7120 sme_setRegInfo(hHal, pConfig->countryCode);
7121 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
7122 }
7123 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07007124 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07007125 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07007126 pConfig->ieee80211d = 1;
7127 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
7128 sme_setRegInfo(hHal, pConfig->countryCode);
7129 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07007130 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007131 else
7132 {
7133 pConfig->ieee80211d = 0;
7134 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307135 /*
7136 * If auto channel is configured i.e. channel is 0,
7137 * so skip channel validation.
7138 */
7139 if( AUTO_CHANNEL_SELECT != pConfig->channel )
7140 {
7141 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
7142 {
7143 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007144 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307145 return -EINVAL;
7146 }
7147 }
7148 else
7149 {
7150 if(1 != pHddCtx->is_dynamic_channel_range_set)
7151 {
7152 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
7153 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
7154 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
7155 }
7156 pHddCtx->is_dynamic_channel_range_set = 0;
7157 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007158 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007159 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007160 {
7161 pConfig->ieee80211d = 0;
7162 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307163
7164#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7165 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7166 pConfig->authType = eSAP_OPEN_SYSTEM;
7167 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7168 pConfig->authType = eSAP_SHARED_KEY;
7169 else
7170 pConfig->authType = eSAP_AUTO_SWITCH;
7171#else
7172 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7173 pConfig->authType = eSAP_OPEN_SYSTEM;
7174 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7175 pConfig->authType = eSAP_SHARED_KEY;
7176 else
7177 pConfig->authType = eSAP_AUTO_SWITCH;
7178#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007179
7180 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307181
7182 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07007183 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
7184
7185 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
7186
7187 /*Set wps station to configured*/
7188 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
7189
7190 if(pIe)
7191 {
7192 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
7193 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007194 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07007195 return -EINVAL;
7196 }
7197 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
7198 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007199 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07007200 /* Check 15 bit of WPS IE as it contain information for wps state
7201 * WPS state
7202 */
7203 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
7204 {
7205 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
7206 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
7207 {
7208 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
7209 }
7210 }
7211 }
7212 else
7213 {
7214 pConfig->wps_state = SAP_WPS_DISABLED;
7215 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307216 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07007217
c_hpothufe599e92014-06-16 11:38:55 +05307218 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7219 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7220 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
7221 eCSR_ENCRYPT_TYPE_NONE;
7222
Jeff Johnson295189b2012-06-20 16:38:30 -07007223 pConfig->RSNWPAReqIELength = 0;
7224 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307225 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007226 WLAN_EID_RSN);
7227 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307228 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007229 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7230 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7231 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307232 /* The actual processing may eventually be more extensive than
7233 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07007234 * by the app.
7235 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307236 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007237 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7238 &RSNEncryptType,
7239 &mcRSNEncryptType,
7240 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007241 &MFPCapable,
7242 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007243 pConfig->pRSNWPAReqIE[1]+2,
7244 pConfig->pRSNWPAReqIE );
7245
7246 if( VOS_STATUS_SUCCESS == status )
7247 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307248 /* Now copy over all the security attributes you have
7249 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007250 * */
7251 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7252 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7253 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7254 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307255 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007256 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007257 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7258 }
7259 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307260
Jeff Johnson295189b2012-06-20 16:38:30 -07007261 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7262 pBeacon->tail, pBeacon->tail_len);
7263
7264 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
7265 {
7266 if (pConfig->pRSNWPAReqIE)
7267 {
7268 /*Mixed mode WPA/WPA2*/
7269 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
7270 pConfig->RSNWPAReqIELength += pIe[1] + 2;
7271 }
7272 else
7273 {
7274 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7275 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7276 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307277 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007278 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7279 &RSNEncryptType,
7280 &mcRSNEncryptType,
7281 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007282 &MFPCapable,
7283 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007284 pConfig->pRSNWPAReqIE[1]+2,
7285 pConfig->pRSNWPAReqIE );
7286
7287 if( VOS_STATUS_SUCCESS == status )
7288 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307289 /* Now copy over all the security attributes you have
7290 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007291 * */
7292 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7293 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7294 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7295 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307296 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007297 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007298 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7299 }
7300 }
7301 }
7302
Jeff Johnson4416a782013-03-25 14:17:50 -07007303 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
7304 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
7305 return -EINVAL;
7306 }
7307
Jeff Johnson295189b2012-06-20 16:38:30 -07007308 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
7309
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007310#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007311 if (params->ssid != NULL)
7312 {
7313 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
7314 pConfig->SSIDinfo.ssid.length = params->ssid_len;
7315 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7316 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7317 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007318#else
7319 if (ssid != NULL)
7320 {
7321 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
7322 pConfig->SSIDinfo.ssid.length = ssid_len;
7323 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7324 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7325 }
7326#endif
7327
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307328 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07007329 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307330
Jeff Johnson295189b2012-06-20 16:38:30 -07007331 /* default value */
7332 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7333 pConfig->num_accept_mac = 0;
7334 pConfig->num_deny_mac = 0;
7335
7336 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7337 pBeacon->tail, pBeacon->tail_len);
7338
7339 /* pIe for black list is following form:
7340 type : 1 byte
7341 length : 1 byte
7342 OUI : 4 bytes
7343 acl type : 1 byte
7344 no of mac addr in black list: 1 byte
7345 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307346 */
7347 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007348 {
7349 pConfig->SapMacaddr_acl = pIe[6];
7350 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007351 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007352 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307353 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
7354 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007355 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7356 for (i = 0; i < pConfig->num_deny_mac; i++)
7357 {
7358 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7359 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307360 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007361 }
7362 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7363 pBeacon->tail, pBeacon->tail_len);
7364
7365 /* pIe for white list is following form:
7366 type : 1 byte
7367 length : 1 byte
7368 OUI : 4 bytes
7369 acl type : 1 byte
7370 no of mac addr in white list: 1 byte
7371 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307372 */
7373 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007374 {
7375 pConfig->SapMacaddr_acl = pIe[6];
7376 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007377 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007378 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307379 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
7380 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007381 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7382 for (i = 0; i < pConfig->num_accept_mac; i++)
7383 {
7384 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7385 acl_entry++;
7386 }
7387 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307388
Jeff Johnson295189b2012-06-20 16:38:30 -07007389 wlan_hdd_set_sapHwmode(pHostapdAdapter);
7390
Jeff Johnsone7245742012-09-05 17:12:55 -07007391#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007392 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307393 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
7394 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05307395 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
7396 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007397 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
7398 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307399 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
7400 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07007401 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307402 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07007403 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307404 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007405
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307406 /* If ACS disable and selected channel <= 14
7407 * OR
7408 * ACS enabled and ACS operating band is choosen as 2.4
7409 * AND
7410 * VHT in 2.4G Disabled
7411 * THEN
7412 * Fallback to 11N mode
7413 */
7414 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
7415 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05307416 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307417 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007418 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307419 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
7420 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007421 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
7422 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007423 }
7424#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307425
Jeff Johnson295189b2012-06-20 16:38:30 -07007426 // ht_capab is not what the name conveys,this is used for protection bitmap
7427 pConfig->ht_capab =
7428 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
7429
7430 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
7431 {
7432 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
7433 return -EINVAL;
7434 }
7435
7436 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307437 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07007438 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
7439 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307440 pConfig->obssProtEnabled =
7441 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07007442
Chet Lanctot8cecea22014-02-11 19:09:36 -08007443#ifdef WLAN_FEATURE_11W
7444 pConfig->mfpCapable = MFPCapable;
7445 pConfig->mfpRequired = MFPRequired;
7446 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
7447 pConfig->mfpCapable, pConfig->mfpRequired);
7448#endif
7449
Arif Hussain6d2a3322013-11-17 19:50:10 -08007450 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07007451 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007452 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
7453 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
7454 (int)pConfig->channel);
7455 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
7456 pConfig->SapHw_mode, pConfig->privacy,
7457 pConfig->authType);
7458 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
7459 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
7460 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
7461 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07007462
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307463 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007464 {
7465 //Bss already started. just return.
7466 //TODO Probably it should update some beacon params.
7467 hddLog( LOGE, "Bss Already started...Ignore the request");
7468 EXIT();
7469 return 0;
7470 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307471
Agarwal Ashish51325b52014-06-16 16:50:49 +05307472 if (vos_max_concurrent_connections_reached()) {
7473 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7474 return -EINVAL;
7475 }
7476
Jeff Johnson295189b2012-06-20 16:38:30 -07007477 pConfig->persona = pHostapdAdapter->device_mode;
7478
Peng Xu2446a892014-09-05 17:21:18 +05307479 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
7480 if ( NULL != psmeConfig)
7481 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307482 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05307483 sme_GetConfigParam(hHal, psmeConfig);
7484 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307485#ifdef WLAN_FEATURE_AP_HT40_24G
7486 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
7487 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
7488 && pHddCtx->cfg_ini->apHT40_24GEnabled)
7489 {
7490 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
7491 sme_UpdateConfig (hHal, psmeConfig);
7492 }
7493#endif
Peng Xu2446a892014-09-05 17:21:18 +05307494 vos_mem_free(psmeConfig);
7495 }
Peng Xuafc34e32014-09-25 13:23:55 +05307496 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05307497
Jeff Johnson295189b2012-06-20 16:38:30 -07007498 pSapEventCallback = hdd_hostapd_SAPEventCB;
7499 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
7500 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
7501 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007502 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007503 return -EINVAL;
7504 }
7505
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307506 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07007507 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
7508
7509 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307510
Jeff Johnson295189b2012-06-20 16:38:30 -07007511 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307512 {
7513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007514 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07007515 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07007516 VOS_ASSERT(0);
7517 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307518
Jeff Johnson295189b2012-06-20 16:38:30 -07007519 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05307520 /* Initialize WMM configuation */
7521 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307522 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007523
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007524#ifdef WLAN_FEATURE_P2P_DEBUG
7525 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
7526 {
7527 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
7528 {
7529 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7530 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007531 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007532 }
7533 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
7534 {
7535 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7536 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007537 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007538 }
7539 }
7540#endif
7541
Jeff Johnson295189b2012-06-20 16:38:30 -07007542 pHostapdState->bCommit = TRUE;
7543 EXIT();
7544
7545 return 0;
7546}
7547
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007548#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307549static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307550 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007551 struct beacon_parameters *params)
7552{
7553 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307554 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307555 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007556
7557 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307558
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307559 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7560 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
7561 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307562 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
7563 hdd_device_modetoString(pAdapter->device_mode),
7564 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007565
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307566 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7567 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307568 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007569 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307570 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007571 }
7572
Agarwal Ashish51325b52014-06-16 16:50:49 +05307573 if (vos_max_concurrent_connections_reached()) {
7574 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7575 return -EINVAL;
7576 }
7577
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307578 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007579 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007580 )
7581 {
7582 beacon_data_t *old,*new;
7583
7584 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307585
Jeff Johnson295189b2012-06-20 16:38:30 -07007586 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307587 {
7588 hddLog(VOS_TRACE_LEVEL_WARN,
7589 FL("already beacon info added to session(%d)"),
7590 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007591 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307592 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007593
7594 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7595
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307596 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07007597 {
7598 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007599 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007600 return -EINVAL;
7601 }
7602
7603 pAdapter->sessionCtx.ap.beacon = new;
7604
7605 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7606 }
7607
7608 EXIT();
7609 return status;
7610}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307611
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307612static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
7613 struct net_device *dev,
7614 struct beacon_parameters *params)
7615{
7616 int ret;
7617
7618 vos_ssr_protect(__func__);
7619 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
7620 vos_ssr_unprotect(__func__);
7621
7622 return ret;
7623}
7624
7625static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007626 struct net_device *dev,
7627 struct beacon_parameters *params)
7628{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307629 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307630 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7631 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307632 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007633
7634 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307635
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307636 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7637 TRACE_CODE_HDD_CFG80211_SET_BEACON,
7638 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
7639 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7640 __func__, hdd_device_modetoString(pAdapter->device_mode),
7641 pAdapter->device_mode);
7642
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307643 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7644 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307645 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007646 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307647 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007648 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307649
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307650 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007651 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307652 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007653 {
7654 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307655
Jeff Johnson295189b2012-06-20 16:38:30 -07007656 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307657
Jeff Johnson295189b2012-06-20 16:38:30 -07007658 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307659 {
7660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7661 FL("session(%d) old and new heads points to NULL"),
7662 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007663 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307664 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007665
7666 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7667
7668 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307669 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007670 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007671 return -EINVAL;
7672 }
7673
7674 pAdapter->sessionCtx.ap.beacon = new;
7675
7676 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7677 }
7678
7679 EXIT();
7680 return status;
7681}
7682
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307683static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
7684 struct net_device *dev,
7685 struct beacon_parameters *params)
7686{
7687 int ret;
7688
7689 vos_ssr_protect(__func__);
7690 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
7691 vos_ssr_unprotect(__func__);
7692
7693 return ret;
7694}
7695
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007696#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7697
7698#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307699static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007700 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007701#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307702static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007703 struct net_device *dev)
7704#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007705{
7706 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07007707 hdd_context_t *pHddCtx = NULL;
7708 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307709 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307710 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007711
7712 ENTER();
7713
7714 if (NULL == pAdapter)
7715 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307716 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007717 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007718 return -ENODEV;
7719 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007720
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307721 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7722 TRACE_CODE_HDD_CFG80211_STOP_AP,
7723 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307724 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7725 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307726 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007727 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307728 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07007729 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007730
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007731 pScanInfo = &pHddCtx->scan_info;
7732
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307733 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7734 __func__, hdd_device_modetoString(pAdapter->device_mode),
7735 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007736
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307737 ret = wlan_hdd_scan_abort(pAdapter);
7738
Girish Gowli4bf7a632014-06-12 13:42:11 +05307739 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07007740 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307741 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7742 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307743
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307744 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07007745 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7747 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08007748
Jeff Johnsone7245742012-09-05 17:12:55 -07007749 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307750 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07007751 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307752 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07007753 }
7754
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05307755 /* Delete all associated STAs before stopping AP/P2P GO */
7756 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05307757 hdd_hostapd_stop(dev);
7758
Jeff Johnson295189b2012-06-20 16:38:30 -07007759 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007760 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007761 )
7762 {
7763 beacon_data_t *old;
7764
7765 old = pAdapter->sessionCtx.ap.beacon;
7766
7767 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307768 {
7769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7770 FL("session(%d) beacon data points to NULL"),
7771 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007772 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307773 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007774
Jeff Johnson295189b2012-06-20 16:38:30 -07007775 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007776
7777 mutex_lock(&pHddCtx->sap_lock);
7778 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7779 {
Jeff Johnson4416a782013-03-25 14:17:50 -07007780 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007781 {
7782 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7783
7784 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7785
7786 if (!VOS_IS_STATUS_SUCCESS(status))
7787 {
7788 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007789 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007790 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307791 }
7792 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007793 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307794 /* BSS stopped, clear the active sessions for this device mode */
7795 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007796 }
7797 mutex_unlock(&pHddCtx->sap_lock);
7798
7799 if(status != VOS_STATUS_SUCCESS)
7800 {
7801 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007802 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007803 return -EINVAL;
7804 }
7805
Jeff Johnson4416a782013-03-25 14:17:50 -07007806 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007807 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
7808 ==eHAL_STATUS_FAILURE)
7809 {
7810 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007811 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007812 }
7813
Jeff Johnson4416a782013-03-25 14:17:50 -07007814 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007815 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7816 eANI_BOOLEAN_FALSE) )
7817 {
7818 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007819 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007820 }
7821
7822 // Reset WNI_CFG_PROBE_RSP Flags
7823 wlan_hdd_reset_prob_rspies(pAdapter);
7824
7825 pAdapter->sessionCtx.ap.beacon = NULL;
7826 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007827#ifdef WLAN_FEATURE_P2P_DEBUG
7828 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
7829 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
7830 {
7831 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
7832 "GO got removed");
7833 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
7834 }
7835#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007836 }
7837 EXIT();
7838 return status;
7839}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007840
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307841#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7842static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
7843 struct net_device *dev)
7844{
7845 int ret;
7846
7847 vos_ssr_protect(__func__);
7848 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
7849 vos_ssr_unprotect(__func__);
7850
7851 return ret;
7852}
7853#else
7854static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7855 struct net_device *dev)
7856{
7857 int ret;
7858
7859 vos_ssr_protect(__func__);
7860 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
7861 vos_ssr_unprotect(__func__);
7862
7863 return ret;
7864}
7865#endif
7866
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007867#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
7868
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307869static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307870 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007871 struct cfg80211_ap_settings *params)
7872{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307873 hdd_adapter_t *pAdapter;
7874 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307875 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007876
7877 ENTER();
7878
Girish Gowlib143d7a2015-02-18 19:39:55 +05307879 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007880 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307881 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05307882 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307883 return -ENODEV;
7884 }
7885
7886 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7887 if (NULL == pAdapter)
7888 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307889 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307890 "%s: HDD adapter is Null", __func__);
7891 return -ENODEV;
7892 }
7893
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307894 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7895 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
7896 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307897 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7898 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307899 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307900 "%s: HDD adapter magic is invalid", __func__);
7901 return -ENODEV;
7902 }
7903
7904 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307905 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307906 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307907 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307908 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307909 }
7910
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307911 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
7912 __func__, hdd_device_modetoString(pAdapter->device_mode),
7913 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307914
7915 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007916 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007917 )
7918 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307919 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007920
7921 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307922
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007923 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307924 {
7925 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
7926 FL("already beacon info added to session(%d)"),
7927 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007928 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307929 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007930
Girish Gowlib143d7a2015-02-18 19:39:55 +05307931#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7932 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7933 &new,
7934 &params->beacon);
7935#else
7936 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7937 &new,
7938 &params->beacon,
7939 params->dtim_period);
7940#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007941
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307942 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007943 {
7944 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307945 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007946 return -EINVAL;
7947 }
7948 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08007949#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07007950 wlan_hdd_cfg80211_set_channel(wiphy, dev,
7951#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
7952 params->channel, params->channel_type);
7953#else
7954 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
7955#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08007956#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007957 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307958 params->ssid_len, params->hidden_ssid,
7959 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007960 }
7961
7962 EXIT();
7963 return status;
7964}
7965
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307966static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
7967 struct net_device *dev,
7968 struct cfg80211_ap_settings *params)
7969{
7970 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007971
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307972 vos_ssr_protect(__func__);
7973 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
7974 vos_ssr_unprotect(__func__);
7975
7976 return ret;
7977}
7978
7979static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007980 struct net_device *dev,
7981 struct cfg80211_beacon_data *params)
7982{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307983 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307984 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307985 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007986
7987 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307988
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307989 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7990 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
7991 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007992 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007993 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307994
7995 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7996 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307997 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007998 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307999 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008000 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008001
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308002 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008003 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308004 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008005 {
8006 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308007
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008008 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308009
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008010 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308011 {
8012 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8013 FL("session(%d) beacon data points to NULL"),
8014 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008015 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308016 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008017
8018 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
8019
8020 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308021 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008022 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008023 return -EINVAL;
8024 }
8025
8026 pAdapter->sessionCtx.ap.beacon = new;
8027
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308028 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
8029 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008030 }
8031
8032 EXIT();
8033 return status;
8034}
8035
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308036static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8037 struct net_device *dev,
8038 struct cfg80211_beacon_data *params)
8039{
8040 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008041
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308042 vos_ssr_protect(__func__);
8043 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
8044 vos_ssr_unprotect(__func__);
8045
8046 return ret;
8047}
8048
8049#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008050
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308051static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008052 struct net_device *dev,
8053 struct bss_parameters *params)
8054{
8055 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308056 hdd_context_t *pHddCtx;
8057 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008058
8059 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308060
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308061 if (NULL == pAdapter)
8062 {
8063 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8064 "%s: HDD adapter is Null", __func__);
8065 return -ENODEV;
8066 }
8067 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308068 ret = wlan_hdd_validate_context(pHddCtx);
8069 if (0 != ret)
8070 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308071 return ret;
8072 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308073 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8074 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
8075 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308076 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8077 __func__, hdd_device_modetoString(pAdapter->device_mode),
8078 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008079
8080 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008081 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308082 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008083 {
8084 /* ap_isolate == -1 means that in change bss, upper layer doesn't
8085 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308086 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07008087 {
8088 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308089 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008090 }
8091
8092 EXIT();
8093 return 0;
8094}
8095
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308096static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
8097 struct net_device *dev,
8098 struct bss_parameters *params)
8099{
8100 int ret;
8101
8102 vos_ssr_protect(__func__);
8103 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
8104 vos_ssr_unprotect(__func__);
8105
8106 return ret;
8107}
Kiet Lam10841362013-11-01 11:36:50 +05308108/* FUNCTION: wlan_hdd_change_country_code_cd
8109* to wait for contry code completion
8110*/
8111void* wlan_hdd_change_country_code_cb(void *pAdapter)
8112{
8113 hdd_adapter_t *call_back_pAdapter = pAdapter;
8114 complete(&call_back_pAdapter->change_country_code);
8115 return NULL;
8116}
8117
Jeff Johnson295189b2012-06-20 16:38:30 -07008118/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308119 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07008120 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
8121 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308122int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008123 struct net_device *ndev,
8124 enum nl80211_iftype type,
8125 u32 *flags,
8126 struct vif_params *params
8127 )
8128{
8129 struct wireless_dev *wdev;
8130 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008131 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07008132 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008133 tCsrRoamProfile *pRoamProfile = NULL;
8134 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308135 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008136 eMib_dot11DesiredBssType connectedBssType;
8137 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308138 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008139
8140 ENTER();
8141
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308142 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008143 {
8144 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8145 "%s: Adapter context is null", __func__);
8146 return VOS_STATUS_E_FAILURE;
8147 }
8148
8149 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8150 if (!pHddCtx)
8151 {
8152 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8153 "%s: HDD context is null", __func__);
8154 return VOS_STATUS_E_FAILURE;
8155 }
8156
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308157 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8158 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
8159 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308160 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308161 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07008162 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308163 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008164 }
8165
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308166 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8167 __func__, hdd_device_modetoString(pAdapter->device_mode),
8168 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008169
Agarwal Ashish51325b52014-06-16 16:50:49 +05308170 if (vos_max_concurrent_connections_reached()) {
8171 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8172 return -EINVAL;
8173 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308174 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07008175 wdev = ndev->ieee80211_ptr;
8176
8177#ifdef WLAN_BTAMP_FEATURE
8178 if((NL80211_IFTYPE_P2P_CLIENT == type)||
8179 (NL80211_IFTYPE_ADHOC == type)||
8180 (NL80211_IFTYPE_AP == type)||
8181 (NL80211_IFTYPE_P2P_GO == type))
8182 {
8183 pHddCtx->isAmpAllowed = VOS_FALSE;
8184 // stop AMP traffic
8185 status = WLANBAP_StopAmp();
8186 if(VOS_STATUS_SUCCESS != status )
8187 {
8188 pHddCtx->isAmpAllowed = VOS_TRUE;
8189 hddLog(VOS_TRACE_LEVEL_FATAL,
8190 "%s: Failed to stop AMP", __func__);
8191 return -EINVAL;
8192 }
8193 }
8194#endif //WLAN_BTAMP_FEATURE
8195 /* Reset the current device mode bit mask*/
8196 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8197
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +05308198 /* Notify Mode change in case of concurrency.
8199 * Below function invokes TDLS teardown Functionality Since TDLS is
8200 * not Supported in case of concurrency i.e Once P2P session
8201 * is detected disable offchannel and teardown TDLS links
8202 */
8203 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
8204
Jeff Johnson295189b2012-06-20 16:38:30 -07008205 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008206 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07008207 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008208 )
8209 {
8210 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008211 if (!pWextState)
8212 {
8213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8214 "%s: pWextState is null", __func__);
8215 return VOS_STATUS_E_FAILURE;
8216 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008217 pRoamProfile = &pWextState->roamProfile;
8218 LastBSSType = pRoamProfile->BSSType;
8219
8220 switch (type)
8221 {
8222 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008223 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008224 hddLog(VOS_TRACE_LEVEL_INFO,
8225 "%s: setting interface Type to INFRASTRUCTURE", __func__);
8226 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008227#ifdef WLAN_FEATURE_11AC
8228 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
8229 {
8230 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
8231 }
8232#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308233 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07008234 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008235 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008236 //Check for sub-string p2p to confirm its a p2p interface
8237 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308238 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008239 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8240 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8241 }
8242 else
8243 {
8244 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008245 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008246 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008247 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05308248
Jeff Johnson295189b2012-06-20 16:38:30 -07008249 case NL80211_IFTYPE_ADHOC:
8250 hddLog(VOS_TRACE_LEVEL_INFO,
8251 "%s: setting interface Type to ADHOC", __func__);
8252 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
8253 pRoamProfile->phyMode =
8254 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07008255 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008256 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +05308257 hdd_set_ibss_ops( pAdapter );
8258 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +05308259
8260 status = hdd_sta_id_hash_attach(pAdapter);
8261 if (VOS_STATUS_SUCCESS != status) {
8262 hddLog(VOS_TRACE_LEVEL_ERROR,
8263 FL("Failed to initialize hash for IBSS"));
8264 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008265 break;
8266
8267 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008268 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008269 {
8270 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8271 "%s: setting interface Type to %s", __func__,
8272 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
8273
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008274 //Cancel any remain on channel for GO mode
8275 if (NL80211_IFTYPE_P2P_GO == type)
8276 {
8277 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
8278 }
Mohit Khanna0f232092012-09-11 14:46:08 -07008279 if (NL80211_IFTYPE_AP == type)
8280 {
8281 /* As Loading WLAN Driver one interface being created for p2p device
8282 * address. This will take one HW STA and the max number of clients
8283 * that can connect to softAP will be reduced by one. so while changing
8284 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
8285 * interface as it is not required in SoftAP mode.
8286 */
8287
8288 // Get P2P Adapter
8289 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
8290
8291 if (pP2pAdapter)
8292 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308293 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05308294 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07008295 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
8296 }
8297 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05308298 //Disable IMPS & BMPS for SAP/GO
8299 if(VOS_STATUS_E_FAILURE ==
8300 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
8301 {
8302 //Fail to Exit BMPS
8303 VOS_ASSERT(0);
8304 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05308305
8306 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
8307
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308308#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07008309
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308310 /* A Mutex Lock is introduced while changing the mode to
8311 * protect the concurrent access for the Adapters by TDLS
8312 * module.
8313 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308314 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308315#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008316 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05308317 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008318 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07008319 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8320 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308321#ifdef FEATURE_WLAN_TDLS
8322 mutex_unlock(&pHddCtx->tdls_lock);
8323#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008324 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
8325 (pConfig->apRandomBssidEnabled))
8326 {
8327 /* To meet Android requirements create a randomized
8328 MAC address of the form 02:1A:11:Fx:xx:xx */
8329 get_random_bytes(&ndev->dev_addr[3], 3);
8330 ndev->dev_addr[0] = 0x02;
8331 ndev->dev_addr[1] = 0x1A;
8332 ndev->dev_addr[2] = 0x11;
8333 ndev->dev_addr[3] |= 0xF0;
8334 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
8335 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08008336 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
8337 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008338 }
8339
Jeff Johnson295189b2012-06-20 16:38:30 -07008340 hdd_set_ap_ops( pAdapter->dev );
8341
Kiet Lam10841362013-11-01 11:36:50 +05308342 /* This is for only SAP mode where users can
8343 * control country through ini.
8344 * P2P GO follows station country code
8345 * acquired during the STA scanning. */
8346 if((NL80211_IFTYPE_AP == type) &&
8347 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
8348 {
8349 int status = 0;
8350 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
8351 "%s: setting country code from INI ", __func__);
8352 init_completion(&pAdapter->change_country_code);
8353 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
8354 (void *)(tSmeChangeCountryCallback)
8355 wlan_hdd_change_country_code_cb,
8356 pConfig->apCntryCode, pAdapter,
8357 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308358 eSIR_FALSE,
8359 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05308360 if (eHAL_STATUS_SUCCESS == status)
8361 {
8362 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308363 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05308364 &pAdapter->change_country_code,
8365 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308366 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05308367 {
8368 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308369 FL("SME Timed out while setting country code %ld"),
8370 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08008371
8372 if (pHddCtx->isLogpInProgress)
8373 {
8374 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8375 "%s: LOGP in Progress. Ignore!!!", __func__);
8376 return -EAGAIN;
8377 }
Kiet Lam10841362013-11-01 11:36:50 +05308378 }
8379 }
8380 else
8381 {
8382 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008383 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05308384 return -EINVAL;
8385 }
8386 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008387 status = hdd_init_ap_mode(pAdapter);
8388 if(status != VOS_STATUS_SUCCESS)
8389 {
8390 hddLog(VOS_TRACE_LEVEL_FATAL,
8391 "%s: Error initializing the ap mode", __func__);
8392 return -EINVAL;
8393 }
8394 hdd_set_conparam(1);
8395
Nirav Shah7e3c8132015-06-22 23:51:42 +05308396 status = hdd_sta_id_hash_attach(pAdapter);
8397 if (VOS_STATUS_SUCCESS != status)
8398 {
8399 hddLog(VOS_TRACE_LEVEL_ERROR,
8400 FL("Failed to initialize hash for AP"));
8401 return -EINVAL;
8402 }
8403
Jeff Johnson295189b2012-06-20 16:38:30 -07008404 /*interface type changed update in wiphy structure*/
8405 if(wdev)
8406 {
8407 wdev->iftype = type;
8408 pHddCtx->change_iface = type;
8409 }
8410 else
8411 {
8412 hddLog(VOS_TRACE_LEVEL_ERROR,
8413 "%s: ERROR !!!! Wireless dev is NULL", __func__);
8414 return -EINVAL;
8415 }
8416 goto done;
8417 }
8418
8419 default:
8420 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8421 __func__);
8422 return -EOPNOTSUPP;
8423 }
8424 }
8425 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008426 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008427 )
8428 {
8429 switch(type)
8430 {
8431 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008432 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008433 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05308434
8435 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308436#ifdef FEATURE_WLAN_TDLS
8437
8438 /* A Mutex Lock is introduced while changing the mode to
8439 * protect the concurrent access for the Adapters by TDLS
8440 * module.
8441 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308442 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308443#endif
c_hpothu002231a2015-02-05 14:58:51 +05308444 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008445 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008446 //Check for sub-string p2p to confirm its a p2p interface
8447 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008448 {
8449 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8450 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8451 }
8452 else
8453 {
8454 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008455 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008456 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008457 hdd_set_conparam(0);
8458 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008459 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
8460 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308461#ifdef FEATURE_WLAN_TDLS
8462 mutex_unlock(&pHddCtx->tdls_lock);
8463#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308464 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008465 if( VOS_STATUS_SUCCESS != status )
8466 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07008467 /* In case of JB, for P2P-GO, only change interface will be called,
8468 * This is the right place to enable back bmps_imps()
8469 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308470 if (pHddCtx->hdd_wlan_suspended)
8471 {
8472 hdd_set_pwrparams(pHddCtx);
8473 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008474 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008475 goto done;
8476 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008477 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008478 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008479 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8480 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008481 goto done;
8482 default:
8483 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8484 __func__);
8485 return -EOPNOTSUPP;
8486
8487 }
8488
8489 }
8490 else
8491 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308492 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
8493 __func__, hdd_device_modetoString(pAdapter->device_mode),
8494 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008495 return -EOPNOTSUPP;
8496 }
8497
8498
8499 if(pRoamProfile)
8500 {
8501 if ( LastBSSType != pRoamProfile->BSSType )
8502 {
8503 /*interface type changed update in wiphy structure*/
8504 wdev->iftype = type;
8505
8506 /*the BSS mode changed, We need to issue disconnect
8507 if connected or in IBSS disconnect state*/
8508 if ( hdd_connGetConnectedBssType(
8509 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
8510 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
8511 {
8512 /*need to issue a disconnect to CSR.*/
8513 INIT_COMPLETION(pAdapter->disconnect_comp_var);
8514 if( eHAL_STATUS_SUCCESS ==
8515 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
8516 pAdapter->sessionId,
8517 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
8518 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308519 ret = wait_for_completion_interruptible_timeout(
8520 &pAdapter->disconnect_comp_var,
8521 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
8522 if (ret <= 0)
8523 {
8524 hddLog(VOS_TRACE_LEVEL_ERROR,
8525 FL("wait on disconnect_comp_var failed %ld"), ret);
8526 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008527 }
8528 }
8529 }
8530 }
8531
8532done:
8533 /*set bitmask based on updated value*/
8534 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07008535
8536 /* Only STA mode support TM now
8537 * all other mode, TM feature should be disabled */
8538 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
8539 (~VOS_STA & pHddCtx->concurrency_mode) )
8540 {
8541 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
8542 }
8543
Jeff Johnson295189b2012-06-20 16:38:30 -07008544#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308545 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05308546 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07008547 {
8548 //we are ok to do AMP
8549 pHddCtx->isAmpAllowed = VOS_TRUE;
8550 }
8551#endif //WLAN_BTAMP_FEATURE
8552 EXIT();
8553 return 0;
8554}
8555
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308556/*
8557 * FUNCTION: wlan_hdd_cfg80211_change_iface
8558 * wrapper function to protect the actual implementation from SSR.
8559 */
8560int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
8561 struct net_device *ndev,
8562 enum nl80211_iftype type,
8563 u32 *flags,
8564 struct vif_params *params
8565 )
8566{
8567 int ret;
8568
8569 vos_ssr_protect(__func__);
8570 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
8571 vos_ssr_unprotect(__func__);
8572
8573 return ret;
8574}
8575
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008576#ifdef FEATURE_WLAN_TDLS
8577static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308578 struct net_device *dev,
8579#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
8580 const u8 *mac,
8581#else
8582 u8 *mac,
8583#endif
8584 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008585{
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008586 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008587 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308588 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308589 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308590 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05308591 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008592
8593 ENTER();
8594
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308595 if (!dev) {
8596 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
8597 return -EINVAL;
8598 }
8599
8600 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8601 if (!pAdapter) {
8602 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
8603 return -EINVAL;
8604 }
8605
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308606 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008607 {
8608 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8609 "Invalid arguments");
8610 return -EINVAL;
8611 }
Hoonki Lee27511902013-03-14 18:19:06 -07008612
8613 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
8614 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
8615 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308616 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -07008617 "%s: TDLS mode is disabled OR not enabled in FW."
8618 MAC_ADDRESS_STR " Request declined.",
8619 __func__, MAC_ADDR_ARRAY(mac));
8620 return -ENOTSUPP;
8621 }
8622
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008623 if (pHddCtx->isLogpInProgress)
8624 {
8625 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8626 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05308627 wlan_hdd_tdls_set_link_status(pAdapter,
8628 mac,
8629 eTDLS_LINK_IDLE,
8630 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008631 return -EBUSY;
8632 }
8633
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308634 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05308635 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008636
8637 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308638 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008639 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
8640 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308641 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008642 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008643 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308644 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008645
8646 /* in add station, we accept existing valid staId if there is */
8647 if ((0 == update) &&
8648 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
8649 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008650 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308651 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008652 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008653 " link_status %d. staId %d. add station ignored.",
8654 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
8655 return 0;
8656 }
8657 /* in change station, we accept only when staId is valid */
8658 if ((1 == update) &&
8659 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
8660 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
8661 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308662 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008663 "%s: " MAC_ADDRESS_STR
8664 " link status %d. staId %d. change station %s.",
8665 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
8666 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
8667 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008668 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008669
8670 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +05308671 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008672 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008673 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8674 "%s: " MAC_ADDRESS_STR
8675 " TDLS setup is ongoing. Request declined.",
8676 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07008677 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008678 }
8679
8680 /* first to check if we reached to maximum supported TDLS peer.
8681 TODO: for now, return -EPERM looks working fine,
8682 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308683 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8684 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008685 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008686 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8687 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308688 " TDLS Max peer already connected. Request declined."
8689 " Num of peers (%d), Max allowed (%d).",
8690 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
8691 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008692 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008693 }
8694 else
8695 {
8696 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308697 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008698 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008699 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008700 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8701 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
8702 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008703 return -EPERM;
8704 }
8705 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008706 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05308707 wlan_hdd_tdls_set_link_status(pAdapter,
8708 mac,
8709 eTDLS_LINK_CONNECTING,
8710 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008711
Jeff Johnsond75fe012013-04-06 10:53:06 -07008712 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308713 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008714 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008716 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008717 if(StaParams->htcap_present)
8718 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308719 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008720 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308721 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008722 "ht_capa->extended_capabilities: %0x",
8723 StaParams->HTCap.extendedHtCapInfo);
8724 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308725 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008726 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308727 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008728 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008729 if(StaParams->vhtcap_present)
8730 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308731 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008732 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
8733 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
8734 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
8735 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008736 {
8737 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008738 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008739 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308740 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008741 "[%d]: %x ", i, StaParams->supported_rates[i]);
8742 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07008743 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308744 else if ((1 == update) && (NULL == StaParams))
8745 {
8746 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8747 "%s : update is true, but staParams is NULL. Error!", __func__);
8748 return -EPERM;
8749 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008750
8751 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
8752
8753 if (!update)
8754 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05308755 /*Before adding sta make sure that device exited from BMPS*/
8756 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
8757 {
8758 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8759 "%s: Adding tdls peer sta. Disable BMPS", __func__);
8760 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
8761 if (status != VOS_STATUS_SUCCESS) {
8762 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
8763 }
8764 }
8765
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308766 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008767 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308768 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05308769 hddLog(VOS_TRACE_LEVEL_ERROR,
8770 FL("Failed to add TDLS peer STA. Enable Bmps"));
8771 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308772 return -EPERM;
8773 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008774 }
8775 else
8776 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308777 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008778 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308779 if (ret != eHAL_STATUS_SUCCESS) {
8780 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
8781 return -EPERM;
8782 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008783 }
8784
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308785 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008786 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
8787
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308788 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008789 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008790 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308791 "%s: timeout waiting for tdls add station indication %ld",
8792 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008793 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008794 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308795
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008796 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
8797 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008798 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008799 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008800 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008801 }
8802
8803 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008804
8805error:
Atul Mittal115287b2014-07-08 13:26:33 +05308806 wlan_hdd_tdls_set_link_status(pAdapter,
8807 mac,
8808 eTDLS_LINK_IDLE,
8809 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008810 return -EPERM;
8811
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008812}
8813#endif
8814
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308815static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008816 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308817#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
8818 const u8 *mac,
8819#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008820 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308821#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008822 struct station_parameters *params)
8823{
8824 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308825 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308826 hdd_context_t *pHddCtx;
8827 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008828 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308829 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008830#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008831 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008832 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308833 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008834#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008835
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308836 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308837
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308838 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308839 if ((NULL == pAdapter))
8840 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308841 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308842 "invalid adapter ");
8843 return -EINVAL;
8844 }
8845
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308846 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8847 TRACE_CODE_HDD_CHANGE_STATION,
8848 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05308849 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308850
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308851 ret = wlan_hdd_validate_context(pHddCtx);
8852 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05308853 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308854 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308855 }
8856
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308857 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8858
8859 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008860 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308861 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8862 "invalid HDD station context");
8863 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008864 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008865 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
8866
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008867 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
8868 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07008869 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008870 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07008871 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308872 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07008873 WLANTL_STA_AUTHENTICATED);
8874
Gopichand Nakkala29149562013-05-10 21:43:41 +05308875 if (status != VOS_STATUS_SUCCESS)
8876 {
8877 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8878 "%s: Not able to change TL state to AUTHENTICATED", __func__);
8879 return -EINVAL;
8880 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008881 }
8882 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07008883 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8884 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308885#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008886 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8887 StaParams.capability = params->capability;
8888 StaParams.uapsd_queues = params->uapsd_queues;
8889 StaParams.max_sp = params->max_sp;
8890
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308891 /* Convert (first channel , number of channels) tuple to
8892 * the total list of channels. This goes with the assumption
8893 * that if the first channel is < 14, then the next channels
8894 * are an incremental of 1 else an incremental of 4 till the number
8895 * of channels.
8896 */
8897 if (0 != params->supported_channels_len) {
8898 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
8899 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
8900 {
8901 int wifi_chan_index;
8902 StaParams.supported_channels[j] = params->supported_channels[i];
8903 wifi_chan_index =
8904 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
8905 no_of_channels = params->supported_channels[i+1];
8906 for(k=1; k <= no_of_channels; k++)
8907 {
8908 StaParams.supported_channels[j+1] =
8909 StaParams.supported_channels[j] + wifi_chan_index;
8910 j+=1;
8911 }
8912 }
8913 StaParams.supported_channels_len = j;
8914 }
8915 vos_mem_copy(StaParams.supported_oper_classes,
8916 params->supported_oper_classes,
8917 params->supported_oper_classes_len);
8918 StaParams.supported_oper_classes_len =
8919 params->supported_oper_classes_len;
8920
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008921 if (0 != params->ext_capab_len)
8922 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
8923 sizeof(StaParams.extn_capability));
8924
8925 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008926 {
8927 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008928 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008929 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008930
8931 StaParams.supported_rates_len = params->supported_rates_len;
8932
8933 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
8934 * The supported_rates array , for all the structures propogating till Add Sta
8935 * to the firmware has to be modified , if the supplicant (ieee80211) is
8936 * modified to send more rates.
8937 */
8938
8939 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
8940 */
8941 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
8942 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
8943
8944 if (0 != StaParams.supported_rates_len) {
8945 int i = 0;
8946 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
8947 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008948 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008949 "Supported Rates with Length %d", StaParams.supported_rates_len);
8950 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008951 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008952 "[%d]: %0x", i, StaParams.supported_rates[i]);
8953 }
8954
8955 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008956 {
8957 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008958 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008959 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008960
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008961 if (0 != params->ext_capab_len ) {
8962 /*Define A Macro : TODO Sunil*/
8963 if ((1<<4) & StaParams.extn_capability[3]) {
8964 isBufSta = 1;
8965 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308966 /* TDLS Channel Switching Support */
8967 if ((1<<6) & StaParams.extn_capability[3]) {
8968 isOffChannelSupported = 1;
8969 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008970 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308971 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
8972 &StaParams, isBufSta,
8973 isOffChannelSupported);
8974
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308975 if (VOS_STATUS_SUCCESS != status) {
8976 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8977 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
8978 return -EINVAL;
8979 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008980 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
8981
8982 if (VOS_STATUS_SUCCESS != status) {
8983 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8984 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
8985 return -EINVAL;
8986 }
8987 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008988#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05308989 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008990 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008991 return status;
8992}
8993
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308994#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
8995static int wlan_hdd_change_station(struct wiphy *wiphy,
8996 struct net_device *dev,
8997 const u8 *mac,
8998 struct station_parameters *params)
8999#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309000static int wlan_hdd_change_station(struct wiphy *wiphy,
9001 struct net_device *dev,
9002 u8 *mac,
9003 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309004#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309005{
9006 int ret;
9007
9008 vos_ssr_protect(__func__);
9009 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
9010 vos_ssr_unprotect(__func__);
9011
9012 return ret;
9013}
9014
Jeff Johnson295189b2012-06-20 16:38:30 -07009015/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309016 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009017 * This function is used to initialize the key information
9018 */
9019#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309020static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009021 struct net_device *ndev,
9022 u8 key_index, bool pairwise,
9023 const u8 *mac_addr,
9024 struct key_params *params
9025 )
9026#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309027static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009028 struct net_device *ndev,
9029 u8 key_index, const u8 *mac_addr,
9030 struct key_params *params
9031 )
9032#endif
9033{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009034 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07009035 tCsrRoamSetKey setKey;
9036 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309037 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009038 v_U32_t roamId= 0xFF;
9039 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009040 hdd_hostapd_state_t *pHostapdState;
9041 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009042 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309043 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009044
9045 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309046
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309047 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9048 TRACE_CODE_HDD_CFG80211_ADD_KEY,
9049 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309050 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9051 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309052 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009053 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309054 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009055 }
9056
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309057 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9058 __func__, hdd_device_modetoString(pAdapter->device_mode),
9059 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009060
9061 if (CSR_MAX_NUM_KEY <= key_index)
9062 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009063 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009064 key_index);
9065
9066 return -EINVAL;
9067 }
9068
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009069 if (CSR_MAX_KEY_LEN < params->key_len)
9070 {
9071 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
9072 params->key_len);
9073
9074 return -EINVAL;
9075 }
9076
9077 hddLog(VOS_TRACE_LEVEL_INFO,
9078 "%s: called with key index = %d & key length %d",
9079 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009080
9081 /*extract key idx, key len and key*/
9082 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9083 setKey.keyId = key_index;
9084 setKey.keyLength = params->key_len;
9085 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
9086
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009087 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009088 {
9089 case WLAN_CIPHER_SUITE_WEP40:
9090 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
9091 break;
9092
9093 case WLAN_CIPHER_SUITE_WEP104:
9094 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
9095 break;
9096
9097 case WLAN_CIPHER_SUITE_TKIP:
9098 {
9099 u8 *pKey = &setKey.Key[0];
9100 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
9101
9102 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
9103
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009104 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07009105
9106 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009107 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009108 |--------------|----------|----------|
9109 <---16bytes---><--8bytes--><--8bytes-->
9110
9111 */
9112 /*Sme expects the 32 bytes key to be in the below order
9113
9114 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009115 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009116 |--------------|----------|----------|
9117 <---16bytes---><--8bytes--><--8bytes-->
9118 */
9119 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009120 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07009121
9122 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009123 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009124
9125 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009126 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009127
9128
9129 break;
9130 }
9131
9132 case WLAN_CIPHER_SUITE_CCMP:
9133 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
9134 break;
9135
9136#ifdef FEATURE_WLAN_WAPI
9137 case WLAN_CIPHER_SUITE_SMS4:
9138 {
9139 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9140 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
9141 params->key, params->key_len);
9142 return 0;
9143 }
9144#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009145
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009146#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009147 case WLAN_CIPHER_SUITE_KRK:
9148 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
9149 break;
9150#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009151
9152#ifdef WLAN_FEATURE_11W
9153 case WLAN_CIPHER_SUITE_AES_CMAC:
9154 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07009155 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07009156#endif
9157
Jeff Johnson295189b2012-06-20 16:38:30 -07009158 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009159 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009160 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309161 status = -EOPNOTSUPP;
9162 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009163 }
9164
9165 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
9166 __func__, setKey.encType);
9167
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009168 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07009169#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9170 (!pairwise)
9171#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009172 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07009173#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009174 )
9175 {
9176 /* set group key*/
9177 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9178 "%s- %d: setting Broadcast key",
9179 __func__, __LINE__);
9180 setKey.keyDirection = eSIR_RX_ONLY;
9181 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9182 }
9183 else
9184 {
9185 /* set pairwise key*/
9186 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9187 "%s- %d: setting pairwise key",
9188 __func__, __LINE__);
9189 setKey.keyDirection = eSIR_TX_RX;
9190 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9191 }
9192 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
9193 {
9194 setKey.keyDirection = eSIR_TX_RX;
9195 /*Set the group key*/
9196 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9197 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07009198
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009199 if ( 0 != status )
9200 {
9201 hddLog(VOS_TRACE_LEVEL_ERROR,
9202 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309203 status = -EINVAL;
9204 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009205 }
9206 /*Save the keys here and call sme_RoamSetKey for setting
9207 the PTK after peer joins the IBSS network*/
9208 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
9209 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309210 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009211 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05309212 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
9213 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
9214 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009215 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009216 if( pHostapdState->bssState == BSS_START )
9217 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009218 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9219 vos_status = wlan_hdd_check_ula_done(pAdapter);
9220
9221 if ( vos_status != VOS_STATUS_SUCCESS )
9222 {
9223 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9224 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9225 __LINE__, vos_status );
9226
9227 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9228
9229 status = -EINVAL;
9230 goto end;
9231 }
9232
Jeff Johnson295189b2012-06-20 16:38:30 -07009233 status = WLANSAP_SetKeySta( pVosContext, &setKey);
9234
9235 if ( status != eHAL_STATUS_SUCCESS )
9236 {
9237 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9238 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9239 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309240 status = -EINVAL;
9241 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009242 }
9243 }
9244
9245 /* Saving WEP keys */
9246 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
9247 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
9248 {
9249 //Save the wep key in ap context. Issue setkey after the BSS is started.
9250 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9251 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
9252 }
9253 else
9254 {
9255 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009256 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009257 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
9258 }
9259 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009260 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
9261 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009262 {
9263 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9264 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9265
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309266#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9267 if (!pairwise)
9268#else
9269 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9270#endif
9271 {
9272 /* set group key*/
9273 if (pHddStaCtx->roam_info.deferKeyComplete)
9274 {
9275 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9276 "%s- %d: Perform Set key Complete",
9277 __func__, __LINE__);
9278 hdd_PerformRoamSetKeyComplete(pAdapter);
9279 }
9280 }
9281
Jeff Johnson295189b2012-06-20 16:38:30 -07009282 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
9283
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08009284 pWextState->roamProfile.Keys.defaultIndex = key_index;
9285
9286
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009287 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009288 params->key, params->key_len);
9289
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309290
Jeff Johnson295189b2012-06-20 16:38:30 -07009291 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9292
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309293 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009294 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309295 __func__, setKey.peerMac[0], setKey.peerMac[1],
9296 setKey.peerMac[2], setKey.peerMac[3],
9297 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009298 setKey.keyDirection);
9299
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009300 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +05309301
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009302 if ( vos_status != VOS_STATUS_SUCCESS )
9303 {
9304 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009305 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9306 __LINE__, vos_status );
9307
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009308 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009309
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009310 status = -EINVAL;
9311 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009312
9313 }
9314
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009315#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309316 /* The supplicant may attempt to set the PTK once pre-authentication
9317 is done. Save the key in the UMAC and include it in the ADD BSS
9318 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009319 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309320 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009321 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309322 hddLog(VOS_TRACE_LEVEL_INFO_MED,
9323 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309324 status = 0;
9325 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309326 }
9327 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
9328 {
9329 hddLog(VOS_TRACE_LEVEL_ERROR,
9330 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309331 status = -EINVAL;
9332 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009333 }
9334#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07009335
9336 /* issue set key request to SME*/
9337 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9338 pAdapter->sessionId, &setKey, &roamId );
9339
9340 if ( 0 != status )
9341 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309342 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009343 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
9344 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309345 status = -EINVAL;
9346 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009347 }
9348
9349
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309350 /* in case of IBSS as there was no information available about WEP keys during
9351 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07009352 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309353 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
9354 !( ( IW_AUTH_KEY_MGMT_802_1X
9355 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07009356 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
9357 )
9358 &&
9359 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
9360 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
9361 )
9362 )
9363 {
9364 setKey.keyDirection = eSIR_RX_ONLY;
9365 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9366
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309367 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009368 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309369 __func__, setKey.peerMac[0], setKey.peerMac[1],
9370 setKey.peerMac[2], setKey.peerMac[3],
9371 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009372 setKey.keyDirection);
9373
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309374 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009375 pAdapter->sessionId, &setKey, &roamId );
9376
9377 if ( 0 != status )
9378 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309379 hddLog(VOS_TRACE_LEVEL_ERROR,
9380 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009381 __func__, status);
9382 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309383 status = -EINVAL;
9384 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009385 }
9386 }
9387 }
9388
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309389end:
9390 /* Need to clear any trace of key value in the memory.
9391 * Thus zero out the memory even though it is local
9392 * variable.
9393 */
9394 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309395 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309396 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009397}
9398
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309399#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9400static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9401 struct net_device *ndev,
9402 u8 key_index, bool pairwise,
9403 const u8 *mac_addr,
9404 struct key_params *params
9405 )
9406#else
9407static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9408 struct net_device *ndev,
9409 u8 key_index, const u8 *mac_addr,
9410 struct key_params *params
9411 )
9412#endif
9413{
9414 int ret;
9415 vos_ssr_protect(__func__);
9416#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9417 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
9418 mac_addr, params);
9419#else
9420 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
9421 params);
9422#endif
9423 vos_ssr_unprotect(__func__);
9424
9425 return ret;
9426}
9427
Jeff Johnson295189b2012-06-20 16:38:30 -07009428/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309429 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009430 * This function is used to get the key information
9431 */
9432#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309433static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309434 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009435 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309436 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009437 const u8 *mac_addr, void *cookie,
9438 void (*callback)(void *cookie, struct key_params*)
9439 )
9440#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309441static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309442 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009443 struct net_device *ndev,
9444 u8 key_index, const u8 *mac_addr, void *cookie,
9445 void (*callback)(void *cookie, struct key_params*)
9446 )
9447#endif
9448{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309449 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309450 hdd_wext_state_t *pWextState = NULL;
9451 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009452 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309453 hdd_context_t *pHddCtx;
9454 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009455
9456 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309457
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309458 if (NULL == pAdapter)
9459 {
9460 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9461 "%s: HDD adapter is Null", __func__);
9462 return -ENODEV;
9463 }
9464
9465 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9466 ret = wlan_hdd_validate_context(pHddCtx);
9467 if (0 != ret)
9468 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309469 return ret;
9470 }
9471
9472 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9473 pRoamProfile = &(pWextState->roamProfile);
9474
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309475 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9476 __func__, hdd_device_modetoString(pAdapter->device_mode),
9477 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309478
Jeff Johnson295189b2012-06-20 16:38:30 -07009479 memset(&params, 0, sizeof(params));
9480
9481 if (CSR_MAX_NUM_KEY <= key_index)
9482 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309483 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07009484 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309485 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009486
9487 switch(pRoamProfile->EncryptionType.encryptionType[0])
9488 {
9489 case eCSR_ENCRYPT_TYPE_NONE:
9490 params.cipher = IW_AUTH_CIPHER_NONE;
9491 break;
9492
9493 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
9494 case eCSR_ENCRYPT_TYPE_WEP40:
9495 params.cipher = WLAN_CIPHER_SUITE_WEP40;
9496 break;
9497
9498 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
9499 case eCSR_ENCRYPT_TYPE_WEP104:
9500 params.cipher = WLAN_CIPHER_SUITE_WEP104;
9501 break;
9502
9503 case eCSR_ENCRYPT_TYPE_TKIP:
9504 params.cipher = WLAN_CIPHER_SUITE_TKIP;
9505 break;
9506
9507 case eCSR_ENCRYPT_TYPE_AES:
9508 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
9509 break;
9510
9511 default:
9512 params.cipher = IW_AUTH_CIPHER_NONE;
9513 break;
9514 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309515
c_hpothuaaf19692014-05-17 17:01:48 +05309516 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9517 TRACE_CODE_HDD_CFG80211_GET_KEY,
9518 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309519
Jeff Johnson295189b2012-06-20 16:38:30 -07009520 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
9521 params.seq_len = 0;
9522 params.seq = NULL;
9523 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
9524 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309525 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009526 return 0;
9527}
9528
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309529#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9530static int wlan_hdd_cfg80211_get_key(
9531 struct wiphy *wiphy,
9532 struct net_device *ndev,
9533 u8 key_index, bool pairwise,
9534 const u8 *mac_addr, void *cookie,
9535 void (*callback)(void *cookie, struct key_params*)
9536 )
9537#else
9538static int wlan_hdd_cfg80211_get_key(
9539 struct wiphy *wiphy,
9540 struct net_device *ndev,
9541 u8 key_index, const u8 *mac_addr, void *cookie,
9542 void (*callback)(void *cookie, struct key_params*)
9543 )
9544#endif
9545{
9546 int ret;
9547
9548 vos_ssr_protect(__func__);
9549#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9550 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
9551 mac_addr, cookie, callback);
9552#else
9553 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
9554 callback);
9555#endif
9556 vos_ssr_unprotect(__func__);
9557
9558 return ret;
9559}
9560
Jeff Johnson295189b2012-06-20 16:38:30 -07009561/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309562 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009563 * This function is used to delete the key information
9564 */
9565#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309566static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009567 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309568 u8 key_index,
9569 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009570 const u8 *mac_addr
9571 )
9572#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309573static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009574 struct net_device *ndev,
9575 u8 key_index,
9576 const u8 *mac_addr
9577 )
9578#endif
9579{
9580 int status = 0;
9581
9582 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309583 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07009584 //it is observed that this is invalidating peer
9585 //key index whenever re-key is done. This is affecting data link.
9586 //It should be ok to ignore del_key.
9587#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309588 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
9589 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009590 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
9591 tCsrRoamSetKey setKey;
9592 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309593
Jeff Johnson295189b2012-06-20 16:38:30 -07009594 ENTER();
9595
9596 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
9597 __func__,pAdapter->device_mode);
9598
9599 if (CSR_MAX_NUM_KEY <= key_index)
9600 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309601 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009602 key_index);
9603
9604 return -EINVAL;
9605 }
9606
9607 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9608 setKey.keyId = key_index;
9609
9610 if (mac_addr)
9611 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9612 else
9613 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
9614
9615 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
9616
9617 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009618 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309619 )
9620 {
9621
9622 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07009623 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9624 if( pHostapdState->bssState == BSS_START)
9625 {
9626 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309627
Jeff Johnson295189b2012-06-20 16:38:30 -07009628 if ( status != eHAL_STATUS_SUCCESS )
9629 {
9630 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9631 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9632 __LINE__, status );
9633 }
9634 }
9635 }
9636 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309637 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07009638 )
9639 {
9640 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9641
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309642 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9643
9644 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009645 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309646 __func__, setKey.peerMac[0], setKey.peerMac[1],
9647 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07009648 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309649 if(pAdapter->sessionCtx.station.conn_info.connState ==
9650 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07009651 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309652 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009653 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309654
Jeff Johnson295189b2012-06-20 16:38:30 -07009655 if ( 0 != status )
9656 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309657 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009658 "%s: sme_RoamSetKey failure, returned %d",
9659 __func__, status);
9660 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9661 return -EINVAL;
9662 }
9663 }
9664 }
9665#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009666 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009667 return status;
9668}
9669
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309670#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9671static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9672 struct net_device *ndev,
9673 u8 key_index,
9674 bool pairwise,
9675 const u8 *mac_addr
9676 )
9677#else
9678static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9679 struct net_device *ndev,
9680 u8 key_index,
9681 const u8 *mac_addr
9682 )
9683#endif
9684{
9685 int ret;
9686
9687 vos_ssr_protect(__func__);
9688#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9689 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
9690 mac_addr);
9691#else
9692 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
9693#endif
9694 vos_ssr_unprotect(__func__);
9695
9696 return ret;
9697}
9698
Jeff Johnson295189b2012-06-20 16:38:30 -07009699/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309700 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009701 * This function is used to set the default tx key index
9702 */
9703#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309704static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009705 struct net_device *ndev,
9706 u8 key_index,
9707 bool unicast, bool multicast)
9708#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309709static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009710 struct net_device *ndev,
9711 u8 key_index)
9712#endif
9713{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309714 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309715 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309716 hdd_wext_state_t *pWextState;
9717 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309718 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009719
9720 ENTER();
9721
Gopichand Nakkala29149562013-05-10 21:43:41 +05309722 if ((NULL == pAdapter))
9723 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309725 "invalid adapter");
9726 return -EINVAL;
9727 }
9728
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309729 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9730 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
9731 pAdapter->sessionId, key_index));
9732
Gopichand Nakkala29149562013-05-10 21:43:41 +05309733 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9734 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9735
9736 if ((NULL == pWextState) || (NULL == pHddStaCtx))
9737 {
9738 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9739 "invalid Wext state or HDD context");
9740 return -EINVAL;
9741 }
9742
Arif Hussain6d2a3322013-11-17 19:50:10 -08009743 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009744 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309745
Jeff Johnson295189b2012-06-20 16:38:30 -07009746 if (CSR_MAX_NUM_KEY <= key_index)
9747 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309748 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009749 key_index);
9750
9751 return -EINVAL;
9752 }
9753
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309754 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9755 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309756 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009757 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309758 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009759 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309760
Jeff Johnson295189b2012-06-20 16:38:30 -07009761 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07009762 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309763 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009764 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309765 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08009766 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309767 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08009768 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07009769 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309770 {
9771 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07009772 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309773
Jeff Johnson295189b2012-06-20 16:38:30 -07009774 tCsrRoamSetKey setKey;
9775 v_U32_t roamId= 0xFF;
9776 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309777
9778 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009779 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309780
Jeff Johnson295189b2012-06-20 16:38:30 -07009781 Keys->defaultIndex = (u8)key_index;
9782 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9783 setKey.keyId = key_index;
9784 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309785
9786 vos_mem_copy(&setKey.Key[0],
9787 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009788 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309789
Gopichand Nakkala29149562013-05-10 21:43:41 +05309790 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309791
9792 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07009793 &pHddStaCtx->conn_info.bssId[0],
9794 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309795
Gopichand Nakkala29149562013-05-10 21:43:41 +05309796 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
9797 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
9798 eCSR_ENCRYPT_TYPE_WEP104)
9799 {
9800 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
9801 even though ap is configured for WEP-40 encryption. In this canse the key length
9802 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
9803 type(104) and switching encryption type to 40*/
9804 pWextState->roamProfile.EncryptionType.encryptionType[0] =
9805 eCSR_ENCRYPT_TYPE_WEP40;
9806 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
9807 eCSR_ENCRYPT_TYPE_WEP40;
9808 }
9809
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309810 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07009811 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309812
Jeff Johnson295189b2012-06-20 16:38:30 -07009813 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309814 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009815 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309816
Jeff Johnson295189b2012-06-20 16:38:30 -07009817 if ( 0 != status )
9818 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309819 hddLog(VOS_TRACE_LEVEL_ERROR,
9820 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009821 status);
9822 return -EINVAL;
9823 }
9824 }
9825 }
9826
9827 /* In SoftAp mode setting key direction for default mode */
9828 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
9829 {
9830 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
9831 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
9832 (eCSR_ENCRYPT_TYPE_AES !=
9833 pWextState->roamProfile.EncryptionType.encryptionType[0])
9834 )
9835 {
9836 /* Saving key direction for default key index to TX default */
9837 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9838 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
9839 }
9840 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309841 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009842 return status;
9843}
9844
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309845#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9846static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9847 struct net_device *ndev,
9848 u8 key_index,
9849 bool unicast, bool multicast)
9850#else
9851static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9852 struct net_device *ndev,
9853 u8 key_index)
9854#endif
9855{
9856 int ret;
9857 vos_ssr_protect(__func__);
9858#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9859 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
9860 multicast);
9861#else
9862 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
9863#endif
9864 vos_ssr_unprotect(__func__);
9865
9866 return ret;
9867}
9868
Jeff Johnson295189b2012-06-20 16:38:30 -07009869/*
9870 * FUNCTION: wlan_hdd_cfg80211_inform_bss
9871 * This function is used to inform the BSS details to nl80211 interface.
9872 */
9873static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
9874 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
9875{
9876 struct net_device *dev = pAdapter->dev;
9877 struct wireless_dev *wdev = dev->ieee80211_ptr;
9878 struct wiphy *wiphy = wdev->wiphy;
9879 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
9880 int chan_no;
9881 int ie_length;
9882 const char *ie;
9883 unsigned int freq;
9884 struct ieee80211_channel *chan;
9885 int rssi = 0;
9886 struct cfg80211_bss *bss = NULL;
9887
Jeff Johnson295189b2012-06-20 16:38:30 -07009888 if( NULL == pBssDesc )
9889 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009890 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009891 return bss;
9892 }
9893
9894 chan_no = pBssDesc->channelId;
9895 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
9896 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
9897
9898 if( NULL == ie )
9899 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009900 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009901 return bss;
9902 }
9903
9904#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9905 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9906 {
9907 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9908 }
9909 else
9910 {
9911 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9912 }
9913#else
9914 freq = ieee80211_channel_to_frequency(chan_no);
9915#endif
9916
9917 chan = __ieee80211_get_channel(wiphy, freq);
9918
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05309919 if (!chan) {
9920 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
9921 return NULL;
9922 }
9923
Abhishek Singhaee43942014-06-16 18:55:47 +05309924 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07009925
Anand N Sunkad9f80b742015-07-30 20:05:51 +05309926 return cfg80211_inform_bss(wiphy, chan,
9927#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
9928 CFG80211_BSS_FTYPE_UNKNOWN,
9929#endif
9930 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309931 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07009932 pBssDesc->capabilityInfo,
9933 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05309934 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07009935}
9936
9937
9938
9939/*
9940 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
9941 * This function is used to inform the BSS details to nl80211 interface.
9942 */
9943struct cfg80211_bss*
9944wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
9945 tSirBssDescription *bss_desc
9946 )
9947{
9948 /*
9949 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
9950 already exists in bss data base of cfg80211 for that particular BSS ID.
9951 Using cfg80211_inform_bss_frame to update the bss entry instead of
9952 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
9953 now there is no possibility to get the mgmt(probe response) frame from PE,
9954 converting bss_desc to ieee80211_mgmt(probe response) and passing to
9955 cfg80211_inform_bss_frame.
9956 */
9957 struct net_device *dev = pAdapter->dev;
9958 struct wireless_dev *wdev = dev->ieee80211_ptr;
9959 struct wiphy *wiphy = wdev->wiphy;
9960 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009961#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9962 qcom_ie_age *qie_age = NULL;
9963 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
9964#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009965 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009966#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009967 const char *ie =
9968 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
9969 unsigned int freq;
9970 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309971 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009972 struct cfg80211_bss *bss_status = NULL;
9973 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
9974 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07009975 hdd_context_t *pHddCtx;
9976 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07009977#ifdef WLAN_OPEN_SOURCE
9978 struct timespec ts;
9979#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009980
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309981
Wilson Yangf80a0542013-10-07 13:02:37 -07009982 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9983 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -07009984 if (0 != status)
9985 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009986 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009987 }
9988
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309989 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07009990 if (!mgmt)
9991 {
9992 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9993 "%s: memory allocation failed ", __func__);
9994 return NULL;
9995 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009996
Jeff Johnson295189b2012-06-20 16:38:30 -07009997 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07009998
9999#ifdef WLAN_OPEN_SOURCE
10000 /* Android does not want the timestamp from the frame.
10001 Instead it wants a monotonic increasing value */
10002 get_monotonic_boottime(&ts);
10003 mgmt->u.probe_resp.timestamp =
10004 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
10005#else
10006 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070010007 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
10008 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070010009
10010#endif
10011
Jeff Johnson295189b2012-06-20 16:38:30 -070010012 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
10013 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010014
10015#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
10016 /* GPS Requirement: need age ie per entry. Using vendor specific. */
10017 /* Assuming this is the last IE, copy at the end */
10018 ie_length -=sizeof(qcom_ie_age);
10019 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
10020 qie_age->element_id = QCOM_VENDOR_IE_ID;
10021 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
10022 qie_age->oui_1 = QCOM_OUI1;
10023 qie_age->oui_2 = QCOM_OUI2;
10024 qie_age->oui_3 = QCOM_OUI3;
10025 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
10026 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
10027#endif
10028
Jeff Johnson295189b2012-06-20 16:38:30 -070010029 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053010030 if (bss_desc->fProbeRsp)
10031 {
10032 mgmt->frame_control |=
10033 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
10034 }
10035 else
10036 {
10037 mgmt->frame_control |=
10038 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
10039 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010040
10041#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010042 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010043 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
10044 {
10045 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10046 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010047 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010048 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
10049
10050 {
10051 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10052 }
10053 else
10054 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010055 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
10056 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070010057 kfree(mgmt);
10058 return NULL;
10059 }
10060#else
10061 freq = ieee80211_channel_to_frequency(chan_no);
10062#endif
10063 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010064 /*when the band is changed on the fly using the GUI, three things are done
10065 * 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)
10066 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
10067 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
10068 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
10069 * and discards the channels correponding to previous band and calls back with zero bss results.
10070 * 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
10071 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
10072 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
10073 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
10074 * So drop the bss and continue to next bss.
10075 */
10076 if(chan == NULL)
10077 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010078 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070010079 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010080 return NULL;
10081 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053010082 /*To keep the rssi icon of the connected AP in the scan window
10083 *and the rssi icon of the wireless networks in sync
10084 * */
10085 if (( eConnectionState_Associated ==
10086 pAdapter->sessionCtx.station.conn_info.connState ) &&
10087 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
10088 pAdapter->sessionCtx.station.conn_info.bssId,
10089 WNI_CFG_BSSID_LEN)) &&
10090 (pHddCtx->hdd_wlan_suspended == FALSE))
10091 {
10092 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
10093 rssi = (pAdapter->rssi * 100);
10094 }
10095 else
10096 {
10097 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
10098 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010099
Nirav Shah20ac06f2013-12-12 18:14:06 +053010100 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053010101 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
10102 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053010103
Jeff Johnson295189b2012-06-20 16:38:30 -070010104 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
10105 frame_len, rssi, GFP_KERNEL);
10106 kfree(mgmt);
10107 return bss_status;
10108}
10109
10110/*
10111 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
10112 * This function is used to update the BSS data base of CFG8011
10113 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010114struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010115 tCsrRoamInfo *pRoamInfo
10116 )
10117{
10118 tCsrRoamConnectedProfile roamProfile;
10119 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10120 struct cfg80211_bss *bss = NULL;
10121
10122 ENTER();
10123
10124 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
10125 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
10126
10127 if (NULL != roamProfile.pBssDesc)
10128 {
Girish Gowlif4b68022014-08-28 23:18:57 +053010129 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10130 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070010131
10132 if (NULL == bss)
10133 {
10134 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
10135 __func__);
10136 }
10137
10138 sme_RoamFreeConnectProfile(hHal, &roamProfile);
10139 }
10140 else
10141 {
10142 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
10143 __func__);
10144 }
10145 return bss;
10146}
10147
10148/*
10149 * FUNCTION: wlan_hdd_cfg80211_update_bss
10150 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010151static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
10152 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070010153 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010154{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010155 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010156 tCsrScanResultInfo *pScanResult;
10157 eHalStatus status = 0;
10158 tScanResultHandle pResult;
10159 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010160 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010161 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070010162 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010163
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010164 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10165 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
10166 NO_SESSION, pAdapter->sessionId));
10167
Wilson Yangf80a0542013-10-07 13:02:37 -070010168 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10169
10170 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070010171 {
Wilson Yangf80a0542013-10-07 13:02:37 -070010172 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10173 "%s:LOGP in Progress. Ignore!!!",__func__);
10174 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010175 }
10176
Wilson Yangf80a0542013-10-07 13:02:37 -070010177
10178 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053010179 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070010180 {
10181 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10182 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
10183 return VOS_STATUS_E_PERM;
10184 }
10185
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010186 if (pAdapter->request != NULL)
10187 {
10188 if ((pAdapter->request->n_ssids == 1)
10189 && (pAdapter->request->ssids != NULL)
10190 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
10191 is_p2p_scan = true;
10192 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010193 /*
10194 * start getting scan results and populate cgf80211 BSS database
10195 */
10196 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
10197
10198 /* no scan results */
10199 if (NULL == pResult)
10200 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010201 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
10202 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053010203 wlan_hdd_get_frame_logs(pAdapter,
10204 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070010205 return status;
10206 }
10207
10208 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
10209
10210 while (pScanResult)
10211 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010212 /*
10213 * cfg80211_inform_bss() is not updating ie field of bss entry, if
10214 * entry already exists in bss data base of cfg80211 for that
10215 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
10216 * bss entry instead of cfg80211_inform_bss, But this call expects
10217 * mgmt packet as input. As of now there is no possibility to get
10218 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070010219 * ieee80211_mgmt(probe response) and passing to c
10220 * fg80211_inform_bss_frame.
10221 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010222 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
10223 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
10224 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010225 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10226 continue; //Skip the non p2p bss entries
10227 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010228 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10229 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010230
Jeff Johnson295189b2012-06-20 16:38:30 -070010231
10232 if (NULL == bss_status)
10233 {
10234 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010235 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010236 }
10237 else
10238 {
Yue Maf49ba872013-08-19 12:04:25 -070010239 cfg80211_put_bss(
10240#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
10241 wiphy,
10242#endif
10243 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010244 }
10245
10246 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10247 }
10248
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010249 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010250 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010251 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010252}
10253
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010254void
10255hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
10256{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010257 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080010258 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010259} /****** end hddPrintMacAddr() ******/
10260
10261void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010262hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010263{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010264 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010265 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010266 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
10267 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
10268 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010269} /****** end hddPrintPmkId() ******/
10270
10271//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
10272//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
10273
10274//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
10275//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
10276
10277#define dump_bssid(bssid) \
10278 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010279 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
10280 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010281 }
10282
10283#define dump_pmkid(pMac, pmkid) \
10284 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010285 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
10286 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010287 }
10288
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070010289#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010290/*
10291 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
10292 * This function is used to notify the supplicant of a new PMKSA candidate.
10293 */
10294int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010295 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010296 int index, bool preauth )
10297{
Jeff Johnsone7245742012-09-05 17:12:55 -070010298#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010299 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010300 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010301
10302 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070010303 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010304
10305 if( NULL == pRoamInfo )
10306 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010307 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010308 return -EINVAL;
10309 }
10310
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010311 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
10312 {
10313 dump_bssid(pRoamInfo->bssid);
10314 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010315 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010316 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010317#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010318 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010319}
10320#endif //FEATURE_WLAN_LFR
10321
Yue Maef608272013-04-08 23:09:17 -070010322#ifdef FEATURE_WLAN_LFR_METRICS
10323/*
10324 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
10325 * 802.11r/LFR metrics reporting function to report preauth initiation
10326 *
10327 */
10328#define MAX_LFR_METRICS_EVENT_LENGTH 100
10329VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
10330 tCsrRoamInfo *pRoamInfo)
10331{
10332 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10333 union iwreq_data wrqu;
10334
10335 ENTER();
10336
10337 if (NULL == pAdapter)
10338 {
10339 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10340 return VOS_STATUS_E_FAILURE;
10341 }
10342
10343 /* create the event */
10344 memset(&wrqu, 0, sizeof(wrqu));
10345 memset(metrics_notification, 0, sizeof(metrics_notification));
10346
10347 wrqu.data.pointer = metrics_notification;
10348 wrqu.data.length = scnprintf(metrics_notification,
10349 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
10350 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10351
10352 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10353
10354 EXIT();
10355
10356 return VOS_STATUS_SUCCESS;
10357}
10358
10359/*
10360 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
10361 * 802.11r/LFR metrics reporting function to report preauth completion
10362 * or failure
10363 */
10364VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
10365 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
10366{
10367 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10368 union iwreq_data wrqu;
10369
10370 ENTER();
10371
10372 if (NULL == pAdapter)
10373 {
10374 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10375 return VOS_STATUS_E_FAILURE;
10376 }
10377
10378 /* create the event */
10379 memset(&wrqu, 0, sizeof(wrqu));
10380 memset(metrics_notification, 0, sizeof(metrics_notification));
10381
10382 scnprintf(metrics_notification, sizeof(metrics_notification),
10383 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
10384 MAC_ADDR_ARRAY(pRoamInfo->bssid));
10385
10386 if (1 == preauth_status)
10387 strncat(metrics_notification, " TRUE", 5);
10388 else
10389 strncat(metrics_notification, " FALSE", 6);
10390
10391 wrqu.data.pointer = metrics_notification;
10392 wrqu.data.length = strlen(metrics_notification);
10393
10394 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10395
10396 EXIT();
10397
10398 return VOS_STATUS_SUCCESS;
10399}
10400
10401/*
10402 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
10403 * 802.11r/LFR metrics reporting function to report handover initiation
10404 *
10405 */
10406VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
10407 tCsrRoamInfo *pRoamInfo)
10408{
10409 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10410 union iwreq_data wrqu;
10411
10412 ENTER();
10413
10414 if (NULL == pAdapter)
10415 {
10416 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10417 return VOS_STATUS_E_FAILURE;
10418 }
10419
10420 /* create the event */
10421 memset(&wrqu, 0, sizeof(wrqu));
10422 memset(metrics_notification, 0, sizeof(metrics_notification));
10423
10424 wrqu.data.pointer = metrics_notification;
10425 wrqu.data.length = scnprintf(metrics_notification,
10426 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
10427 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10428
10429 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10430
10431 EXIT();
10432
10433 return VOS_STATUS_SUCCESS;
10434}
10435#endif
10436
Jeff Johnson295189b2012-06-20 16:38:30 -070010437/*
10438 * FUNCTION: hdd_cfg80211_scan_done_callback
10439 * scanning callback function, called after finishing scan
10440 *
10441 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010442static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070010443 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
10444{
10445 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010446 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070010447 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010448 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010449 struct cfg80211_scan_request *req = NULL;
10450 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010451 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010452 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010453 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010454 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010455
10456 ENTER();
10457
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010458 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053010459 if (NULL == pHddCtx) {
10460 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010461 goto allow_suspend;
10462 }
10463
10464 pScanInfo = &pHddCtx->scan_info;
10465
Jeff Johnson295189b2012-06-20 16:38:30 -070010466 hddLog(VOS_TRACE_LEVEL_INFO,
10467 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080010468 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010469 __func__, halHandle, pContext, (int) scanId, (int) status);
10470
Kiet Lamac06e2c2013-10-23 16:25:07 +053010471 pScanInfo->mScanPendingCounter = 0;
10472
Jeff Johnson295189b2012-06-20 16:38:30 -070010473 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010474 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070010475 &pScanInfo->scan_req_completion_event,
10476 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010477 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070010478 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010479 hddLog(VOS_TRACE_LEVEL_ERROR,
10480 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070010481 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010482 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010483 }
10484
Yue Maef608272013-04-08 23:09:17 -070010485 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010486 {
10487 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010488 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010489 }
10490
10491 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010492 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070010493 {
10494 hddLog(VOS_TRACE_LEVEL_INFO,
10495 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010496 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070010497 (int) scanId);
10498 }
10499
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010500 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010501 pAdapter);
10502
10503 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010504 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010505
10506
10507 /* If any client wait scan result through WEXT
10508 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010509 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070010510 {
10511 /* The other scan request waiting for current scan finish
10512 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010513 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010514 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010515 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070010516 }
10517 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010518 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010519 {
10520 struct net_device *dev = pAdapter->dev;
10521 union iwreq_data wrqu;
10522 int we_event;
10523 char *msg;
10524
10525 memset(&wrqu, '\0', sizeof(wrqu));
10526 we_event = SIOCGIWSCAN;
10527 msg = NULL;
10528 wireless_send_event(dev, we_event, &wrqu, msg);
10529 }
10530 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010531 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010532
10533 /* Get the Scan Req */
10534 req = pAdapter->request;
10535
10536 if (!req)
10537 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010538 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010539 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010540 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010541 }
10542
Jeff Johnson295189b2012-06-20 16:38:30 -070010543 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070010544 /* Scan is no longer pending */
10545 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010546
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010547 /* last_scan_timestamp is used to decide if new scan
10548 * is needed or not on station interface. If last station
10549 * scan time and new station scan time is less then
10550 * last_scan_timestamp ; driver will return cached scan.
10551 */
10552 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
10553 {
10554 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
10555
10556 if ( req->n_channels )
10557 {
10558 for (i = 0; i < req->n_channels ; i++ )
10559 {
10560 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
10561 }
10562 /* store no of channel scanned */
10563 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
10564 }
10565
10566 }
10567
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070010568 /*
10569 * cfg80211_scan_done informing NL80211 about completion
10570 * of scanning
10571 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010572 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
10573 {
10574 aborted = true;
10575 }
10576 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080010577 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010578
Siddharth Bhal76972212014-10-15 16:22:51 +053010579 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
10580 /* Generate new random mac addr for next scan */
10581 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
10582 hdd_processSpoofMacAddrRequest(pHddCtx);
10583 }
10584
Jeff Johnsone7245742012-09-05 17:12:55 -070010585allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010586 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010587 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070010588
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010589 /* Acquire wakelock to handle the case where APP's tries to suspend
10590 * immediatly after the driver gets connect request(i.e after scan)
10591 * from supplicant, this result in app's is suspending and not able
10592 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010593 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010594
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010595#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010596 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010597#endif
10598
Jeff Johnson295189b2012-06-20 16:38:30 -070010599 EXIT();
10600 return 0;
10601}
10602
10603/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053010604 * FUNCTION: hdd_isConnectionInProgress
10605 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010606 *
10607 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010608v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010609{
10610 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10611 hdd_station_ctx_t *pHddStaCtx = NULL;
10612 hdd_adapter_t *pAdapter = NULL;
10613 VOS_STATUS status = 0;
10614 v_U8_t staId = 0;
10615 v_U8_t *staMac = NULL;
10616
c_hpothu9b781ba2013-12-30 20:57:45 +053010617 if (TRUE == pHddCtx->btCoexModeSet)
10618 {
10619 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053010620 FL("BTCoex Mode operation in progress"));
10621 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053010622 }
10623
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010624 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10625
10626 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10627 {
10628 pAdapter = pAdapterNode->pAdapter;
10629
10630 if( pAdapter )
10631 {
10632 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010633 "%s: Adapter with device mode %s (%d) exists",
10634 __func__, hdd_device_modetoString(pAdapter->device_mode),
10635 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010636 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053010637 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10638 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
10639 (eConnectionState_Connecting ==
10640 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
10641 {
10642 hddLog(VOS_TRACE_LEVEL_ERROR,
10643 "%s: %p(%d) Connection is in progress", __func__,
10644 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10645 return VOS_TRUE;
10646 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010647 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053010648 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010649 {
10650 hddLog(VOS_TRACE_LEVEL_ERROR,
10651 "%s: %p(%d) Reassociation is in progress", __func__,
10652 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10653 return VOS_TRUE;
10654 }
10655 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010656 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10657 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010658 {
10659 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10660 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010661 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010662 {
10663 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
10664 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010665 "%s: client " MAC_ADDRESS_STR
10666 " is in the middle of WPS/EAPOL exchange.", __func__,
10667 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010668 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010669 }
10670 }
10671 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
10672 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
10673 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010674 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10675 ptSapContext pSapCtx = NULL;
10676 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10677 if(pSapCtx == NULL){
10678 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10679 FL("psapCtx is NULL"));
10680 return VOS_FALSE;
10681 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010682 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
10683 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010684 if ((pSapCtx->aStaInfo[staId].isUsed) &&
10685 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010686 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010687 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010688
10689 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010690 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
10691 "middle of WPS/EAPOL exchange.", __func__,
10692 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010693 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010694 }
10695 }
10696 }
10697 }
10698 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10699 pAdapterNode = pNext;
10700 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053010701 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010702}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010703
10704/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010705 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070010706 * this scan respond to scan trigger and update cfg80211 scan database
10707 * later, scan dump command can be used to recieve scan results
10708 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010709int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010710#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10711 struct net_device *dev,
10712#endif
10713 struct cfg80211_scan_request *request)
10714{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010715 hdd_adapter_t *pAdapter = NULL;
10716 hdd_context_t *pHddCtx = NULL;
10717 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010718 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010719 tCsrScanRequest scanRequest;
10720 tANI_U8 *channelList = NULL, i;
10721 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010722 int status;
10723 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010724 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010725 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053010726 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010727 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053010728 v_S7_t rssi=0;
10729 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010730
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010731#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
10732 struct net_device *dev = NULL;
10733 if (NULL == request)
10734 {
10735 hddLog(VOS_TRACE_LEVEL_ERROR,
10736 "%s: scan req param null", __func__);
10737 return -EINVAL;
10738 }
10739 dev = request->wdev->netdev;
10740#endif
10741
10742 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
10743 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
10744 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10745
Jeff Johnson295189b2012-06-20 16:38:30 -070010746 ENTER();
10747
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010748 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10749 __func__, hdd_device_modetoString(pAdapter->device_mode),
10750 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010751
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010752 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010753 if (0 != status)
10754 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010755 return status;
10756 }
10757
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010758 if (NULL == pwextBuf)
10759 {
10760 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
10761 __func__);
10762 return -EIO;
10763 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010764 cfg_param = pHddCtx->cfg_ini;
10765 pScanInfo = &pHddCtx->scan_info;
10766
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053010767 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10768 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
10769 {
10770 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
10771 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
10772 }
10773
Jeff Johnson295189b2012-06-20 16:38:30 -070010774#ifdef WLAN_BTAMP_FEATURE
10775 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010776 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070010777 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010778 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010779 "%s: No scanning when AMP is on", __func__);
10780 return -EOPNOTSUPP;
10781 }
10782#endif
10783 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010784 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010785 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010786 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010787 "%s: Not scanning on device_mode = %s (%d)",
10788 __func__, hdd_device_modetoString(pAdapter->device_mode),
10789 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010790 return -EOPNOTSUPP;
10791 }
10792
10793 if (TRUE == pScanInfo->mScanPending)
10794 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010795 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
10796 {
10797 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
10798 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010799 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010800 }
10801
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010802 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070010803 //Channel and action frame is pending
10804 //Otherwise Cancel Remain On Channel and allow Scan
10805 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010806 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070010807 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010808 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010809 return -EBUSY;
10810 }
10811
Jeff Johnson295189b2012-06-20 16:38:30 -070010812 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
10813 {
10814 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080010815 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010816 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010817 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010818 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
10819 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010820 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010821 "%s: MAX TM Level Scan not allowed", __func__);
10822 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010823 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010824 }
10825 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
10826
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010827 /* Check if scan is allowed at this point of time.
10828 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010829 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010830 {
10831 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
10832 return -EBUSY;
10833 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010834
Jeff Johnson295189b2012-06-20 16:38:30 -070010835 vos_mem_zero( &scanRequest, sizeof(scanRequest));
10836
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010837 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
10838 * Becasue of this, driver is assuming that this is not wildcard scan and so
10839 * is not aging out the scan results.
10840 */
10841 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010842 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010843 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010844 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010845
10846 if ((request->ssids) && (0 < request->n_ssids))
10847 {
10848 tCsrSSIDInfo *SsidInfo;
10849 int j;
10850 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
10851 /* Allocate num_ssid tCsrSSIDInfo structure */
10852 SsidInfo = scanRequest.SSIDs.SSIDList =
10853 ( tCsrSSIDInfo *)vos_mem_malloc(
10854 request->n_ssids*sizeof(tCsrSSIDInfo));
10855
10856 if(NULL == scanRequest.SSIDs.SSIDList)
10857 {
10858 hddLog(VOS_TRACE_LEVEL_ERROR,
10859 "%s: memory alloc failed SSIDInfo buffer", __func__);
10860 return -ENOMEM;
10861 }
10862
10863 /* copy all the ssid's and their length */
10864 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
10865 {
10866 /* get the ssid length */
10867 SsidInfo->SSID.length = request->ssids[j].ssid_len;
10868 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
10869 SsidInfo->SSID.length);
10870 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
10871 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
10872 j, SsidInfo->SSID.ssId);
10873 }
10874 /* set the scan type to active */
10875 scanRequest.scanType = eSIR_ACTIVE_SCAN;
10876 }
10877 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070010878 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010879 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10880 TRACE_CODE_HDD_CFG80211_SCAN,
10881 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070010882 /* set the scan type to active */
10883 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010884 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010885 else
10886 {
10887 /*Set the scan type to default type, in this case it is ACTIVE*/
10888 scanRequest.scanType = pScanInfo->scan_mode;
10889 }
10890 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
10891 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070010892
10893 /* set BSSType to default type */
10894 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
10895
10896 /*TODO: scan the requested channels only*/
10897
10898 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010899 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070010900 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010901 hddLog(VOS_TRACE_LEVEL_WARN,
10902 "No of Scan Channels exceeded limit: %d", request->n_channels);
10903 request->n_channels = MAX_CHANNEL;
10904 }
10905
10906 hddLog(VOS_TRACE_LEVEL_INFO,
10907 "No of Scan Channels: %d", request->n_channels);
10908
10909
10910 if( request->n_channels )
10911 {
10912 char chList [(request->n_channels*5)+1];
10913 int len;
10914 channelList = vos_mem_malloc( request->n_channels );
10915 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053010916 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010917 hddLog(VOS_TRACE_LEVEL_ERROR,
10918 "%s: memory alloc failed channelList", __func__);
10919 status = -ENOMEM;
10920 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053010921 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010922
10923 for( i = 0, len = 0; i < request->n_channels ; i++ )
10924 {
10925 channelList[i] = request->channels[i]->hw_value;
10926 len += snprintf(chList+len, 5, "%d ", channelList[i]);
10927 }
10928
Nirav Shah20ac06f2013-12-12 18:14:06 +053010929 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010930 "Channel-List: %s ", chList);
10931 }
c_hpothu53512302014-04-15 18:49:53 +053010932
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010933 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
10934 scanRequest.ChannelInfo.ChannelList = channelList;
10935
10936 /* set requestType to full scan */
10937 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10938
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010939 /* if there is back to back scan happening in driver with in
10940 * nDeferScanTimeInterval interval driver should defer new scan request
10941 * and should provide last cached scan results instead of new channel list.
10942 * This rule is not applicable if scan is p2p scan.
10943 * This condition will work only in case when last request no of channels
10944 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053010945 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053010946 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010947 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010948
Sushant Kaushik86592172015-04-27 16:35:03 +053010949 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
10950 /* if wps ie is NULL , then only defer scan */
10951 if ( pWpsIe == NULL &&
10952 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053010953 {
10954 if ( pScanInfo->last_scan_timestamp !=0 &&
10955 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
10956 {
10957 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
10958 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
10959 vos_mem_compare(pScanInfo->last_scan_channelList,
10960 channelList, pScanInfo->last_scan_numChannels))
10961 {
10962 hddLog(VOS_TRACE_LEVEL_WARN,
10963 " New and old station scan time differ is less then %u",
10964 pHddCtx->cfg_ini->nDeferScanTimeInterval);
10965
10966 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010967 pAdapter);
10968
Agarwal Ashish57e84372014-12-05 18:26:53 +053010969 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010970 "Return old cached scan as all channels and no of channels are same");
10971
Agarwal Ashish57e84372014-12-05 18:26:53 +053010972 if (0 > ret)
10973 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010974
Agarwal Ashish57e84372014-12-05 18:26:53 +053010975 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010976
10977 status = eHAL_STATUS_SUCCESS;
10978 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053010979 }
10980 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010981 }
10982
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010983 /* Flush the scan results(only p2p beacons) for STA scan and P2P
10984 * search (Flush on both full scan and social scan but not on single
10985 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
10986 */
10987
10988 /* Supplicant does single channel scan after 8-way handshake
10989 * and in that case driver shoudnt flush scan results. If
10990 * driver flushes the scan results here and unfortunately if
10991 * the AP doesnt respond to our probe req then association
10992 * fails which is not desired
10993 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010994 if ((request->n_ssids == 1)
10995 && (request->ssids != NULL)
10996 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
10997 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010998
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010999 if( is_p2p_scan ||
11000 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011001 {
11002 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
11003 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
11004 pAdapter->sessionId );
11005 }
11006
11007 if( request->ie_len )
11008 {
11009 /* save this for future association (join requires this) */
11010 /*TODO: Array needs to be converted to dynamic allocation,
11011 * as multiple ie.s can be sent in cfg80211_scan_request structure
11012 * CR 597966
11013 */
11014 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
11015 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
11016 pScanInfo->scanAddIE.length = request->ie_len;
11017
11018 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11019 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11020 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011021 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011022 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070011023 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011024 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
11025 memcpy( pwextBuf->roamProfile.addIEScan,
11026 request->ie, request->ie_len);
11027 }
11028 else
11029 {
11030 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
11031 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011032 }
11033
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011034 }
11035 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
11036 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
11037
11038 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
11039 request->ie_len);
11040 if (pP2pIe != NULL)
11041 {
11042#ifdef WLAN_FEATURE_P2P_DEBUG
11043 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
11044 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
11045 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053011046 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011047 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
11048 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11049 "Go nego completed to Connection is started");
11050 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11051 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053011052 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011053 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
11054 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011055 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011056 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
11057 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11058 "Disconnected state to Connection is started");
11059 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11060 "for 4way Handshake");
11061 }
11062#endif
11063
11064 /* no_cck will be set during p2p find to disable 11b rates */
11065 if(TRUE == request->no_cck)
11066 {
11067 hddLog(VOS_TRACE_LEVEL_INFO,
11068 "%s: This is a P2P Search", __func__);
11069 scanRequest.p2pSearch = 1;
11070
11071 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053011072 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011073 /* set requestType to P2P Discovery */
11074 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
11075 }
11076
11077 /*
11078 Skip Dfs Channel in case of P2P Search
11079 if it is set in ini file
11080 */
11081 if(cfg_param->skipDfsChnlInP2pSearch)
11082 {
11083 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011084 }
11085 else
11086 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011087 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011088 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011089
Agarwal Ashish4f616132013-12-30 23:32:50 +053011090 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011091 }
11092 }
11093
11094 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
11095
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011096#ifdef FEATURE_WLAN_TDLS
11097 /* if tdls disagree scan right now, return immediately.
11098 tdls will schedule the scan when scan is allowed. (return SUCCESS)
11099 or will reject the scan if any TDLS is in progress. (return -EBUSY)
11100 */
11101 status = wlan_hdd_tdls_scan_callback (pAdapter,
11102 wiphy,
11103#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11104 dev,
11105#endif
11106 request);
11107 if(status <= 0)
11108 {
11109 if(!status)
11110 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
11111 "scan rejected %d", __func__, status);
11112 else
11113 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
11114 __func__, status);
11115
11116 return status;
11117 }
11118#endif
11119
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011120 /* acquire the wakelock to avoid the apps suspend during the scan. To
11121 * address the following issues.
11122 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
11123 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
11124 * for long time, this result in apps running at full power for long time.
11125 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
11126 * be stuck in full power because of resume BMPS
11127 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011128 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011129
Nirav Shah20ac06f2013-12-12 18:14:06 +053011130 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11131 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011132 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
11133 scanRequest.requestType, scanRequest.scanType,
11134 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053011135 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
11136
Siddharth Bhal76972212014-10-15 16:22:51 +053011137 if (pHddCtx->spoofMacAddr.isEnabled)
11138 {
11139 hddLog(VOS_TRACE_LEVEL_INFO,
11140 "%s: MAC Spoofing enabled for current scan", __func__);
11141 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
11142 * to fill TxBds for probe request during current scan
11143 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011144 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053011145 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011146
11147 if(status != VOS_STATUS_SUCCESS)
11148 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011149 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011150 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053011151#ifdef FEATURE_WLAN_TDLS
11152 wlan_hdd_tdls_scan_done_callback(pAdapter);
11153#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011154 goto free_mem;
11155 }
Siddharth Bhal76972212014-10-15 16:22:51 +053011156 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053011157 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070011158 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011159 pAdapter->sessionId, &scanRequest, &scanId,
11160 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070011161
Jeff Johnson295189b2012-06-20 16:38:30 -070011162 if (eHAL_STATUS_SUCCESS != status)
11163 {
11164 hddLog(VOS_TRACE_LEVEL_ERROR,
11165 "%s: sme_ScanRequest returned error %d", __func__, status);
11166 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011167 if(eHAL_STATUS_RESOURCES == status)
11168 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011169 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
11170 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011171 status = -EBUSY;
11172 } else {
11173 status = -EIO;
11174 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011175 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011176
11177#ifdef FEATURE_WLAN_TDLS
11178 wlan_hdd_tdls_scan_done_callback(pAdapter);
11179#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011180 goto free_mem;
11181 }
11182
11183 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011184 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011185 pAdapter->request = request;
11186 pScanInfo->scanId = scanId;
11187
11188 complete(&pScanInfo->scan_req_completion_event);
11189
11190free_mem:
11191 if( scanRequest.SSIDs.SSIDList )
11192 {
11193 vos_mem_free(scanRequest.SSIDs.SSIDList);
11194 }
11195
11196 if( channelList )
11197 vos_mem_free( channelList );
11198
11199 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011200 return status;
11201}
11202
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011203int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
11204#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11205 struct net_device *dev,
11206#endif
11207 struct cfg80211_scan_request *request)
11208{
11209 int ret;
11210
11211 vos_ssr_protect(__func__);
11212 ret = __wlan_hdd_cfg80211_scan(wiphy,
11213#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11214 dev,
11215#endif
11216 request);
11217 vos_ssr_unprotect(__func__);
11218
11219 return ret;
11220}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011221
11222void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
11223{
11224 v_U8_t iniDot11Mode =
11225 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
11226 eHddDot11Mode hddDot11Mode = iniDot11Mode;
11227
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011228 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
11229 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011230 switch ( iniDot11Mode )
11231 {
11232 case eHDD_DOT11_MODE_AUTO:
11233 case eHDD_DOT11_MODE_11ac:
11234 case eHDD_DOT11_MODE_11ac_ONLY:
11235#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053011236 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
11237 sme_IsFeatureSupportedByFW(DOT11AC) )
11238 hddDot11Mode = eHDD_DOT11_MODE_11ac;
11239 else
11240 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011241#else
11242 hddDot11Mode = eHDD_DOT11_MODE_11n;
11243#endif
11244 break;
11245 case eHDD_DOT11_MODE_11n:
11246 case eHDD_DOT11_MODE_11n_ONLY:
11247 hddDot11Mode = eHDD_DOT11_MODE_11n;
11248 break;
11249 default:
11250 hddDot11Mode = iniDot11Mode;
11251 break;
11252 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011253#ifdef WLAN_FEATURE_AP_HT40_24G
11254 if (operationChannel > SIR_11B_CHANNEL_END)
11255#endif
11256 {
11257 /* This call decides required channel bonding mode */
11258 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011259 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
11260 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011261 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011262}
11263
Jeff Johnson295189b2012-06-20 16:38:30 -070011264/*
11265 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011266 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011267 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011268int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011269 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070011270{
11271 int status = 0;
11272 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080011273 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011274 v_U32_t roamId;
11275 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070011276 eCsrAuthType RSNAuthType;
11277
11278 ENTER();
11279
11280 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080011281 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11282
11283 status = wlan_hdd_validate_context(pHddCtx);
11284 if (status)
11285 {
Yue Mae36e3552014-03-05 17:06:20 -080011286 return status;
11287 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011288
Jeff Johnson295189b2012-06-20 16:38:30 -070011289 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
11290 {
11291 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
11292 return -EINVAL;
11293 }
11294
11295 pRoamProfile = &pWextState->roamProfile;
11296
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011297 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070011298 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011299 hdd_station_ctx_t *pHddStaCtx;
11300 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011301
Siddharth Bhalda0d1622015-04-24 15:47:49 +053011302 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
11303
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011304 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070011305 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
11306 {
11307 /*QoS not enabled in cfg file*/
11308 pRoamProfile->uapsd_mask = 0;
11309 }
11310 else
11311 {
11312 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011313 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070011314 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
11315 }
11316
11317 pRoamProfile->SSIDs.numOfSSIDs = 1;
11318 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
11319 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011320 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070011321 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
11322 ssid, ssid_len);
11323
11324 if (bssid)
11325 {
11326 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
11327 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
11328 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011329 /* Save BSSID in seperate variable as well, as RoamProfile
11330 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070011331 case of join failure we should send valid BSSID to supplicant
11332 */
11333 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
11334 WNI_CFG_BSSID_LEN);
11335 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070011336 else
11337 {
11338 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
11339 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011340
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011341 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
11342 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011343 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
11344 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011345 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011346 /*set gen ie*/
11347 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
11348 /*set auth*/
11349 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
11350 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011351#ifdef FEATURE_WLAN_WAPI
11352 if (pAdapter->wapi_info.nWapiMode)
11353 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011354 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011355 switch (pAdapter->wapi_info.wapiAuthMode)
11356 {
11357 case WAPI_AUTH_MODE_PSK:
11358 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011359 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011360 pAdapter->wapi_info.wapiAuthMode);
11361 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
11362 break;
11363 }
11364 case WAPI_AUTH_MODE_CERT:
11365 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011366 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011367 pAdapter->wapi_info.wapiAuthMode);
11368 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
11369 break;
11370 }
11371 } // End of switch
11372 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
11373 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
11374 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011375 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011376 pRoamProfile->AuthType.numEntries = 1;
11377 pRoamProfile->EncryptionType.numEntries = 1;
11378 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11379 pRoamProfile->mcEncryptionType.numEntries = 1;
11380 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11381 }
11382 }
11383#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011384#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011385 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011386 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11387 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
11388 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011389 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
11390 sizeof (tSirGtkOffloadParams));
11391 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011392 }
11393#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011394 pRoamProfile->csrPersona = pAdapter->device_mode;
11395
Jeff Johnson32d95a32012-09-10 13:15:23 -070011396 if( operatingChannel )
11397 {
11398 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
11399 pRoamProfile->ChannelInfo.numOfChannels = 1;
11400 }
Chet Lanctot186b5732013-03-18 10:26:30 -070011401 else
11402 {
11403 pRoamProfile->ChannelInfo.ChannelList = NULL;
11404 pRoamProfile->ChannelInfo.numOfChannels = 0;
11405 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011406 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
11407 {
11408 hdd_select_cbmode(pAdapter,operatingChannel);
11409 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011410
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011411 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
11412 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011413 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011414 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011415 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
11416 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011417 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11418 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053011419 {
11420 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11421 "%s: Set HDD connState to eConnectionState_Connecting",
11422 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011423 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
11424 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053011425 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011426 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011427 pAdapter->sessionId, pRoamProfile, &roamId);
11428
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011429 if ((eHAL_STATUS_SUCCESS != status) &&
11430 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11431 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011432
11433 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011434 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
11435 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
11436 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011437 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011438 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011439 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011440
11441 pRoamProfile->ChannelInfo.ChannelList = NULL;
11442 pRoamProfile->ChannelInfo.numOfChannels = 0;
11443
Jeff Johnson295189b2012-06-20 16:38:30 -070011444 }
11445 else
11446 {
11447 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
11448 return -EINVAL;
11449 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011450 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011451 return status;
11452}
11453
11454/*
11455 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
11456 * This function is used to set the authentication type (OPEN/SHARED).
11457 *
11458 */
11459static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
11460 enum nl80211_auth_type auth_type)
11461{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011462 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011463 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11464
11465 ENTER();
11466
11467 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011468 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070011469 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011470 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011471 hddLog(VOS_TRACE_LEVEL_INFO,
11472 "%s: set authentication type to AUTOSWITCH", __func__);
11473 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
11474 break;
11475
11476 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011477#ifdef WLAN_FEATURE_VOWIFI_11R
11478 case NL80211_AUTHTYPE_FT:
11479#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011480 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011481 "%s: set authentication type to OPEN", __func__);
11482 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
11483 break;
11484
11485 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011486 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011487 "%s: set authentication type to SHARED", __func__);
11488 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
11489 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011490#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011491 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011492 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011493 "%s: set authentication type to CCKM WPA", __func__);
11494 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
11495 break;
11496#endif
11497
11498
11499 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011500 hddLog(VOS_TRACE_LEVEL_ERROR,
11501 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011502 auth_type);
11503 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
11504 return -EINVAL;
11505 }
11506
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011507 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011508 pHddStaCtx->conn_info.authType;
11509 return 0;
11510}
11511
11512/*
11513 * FUNCTION: wlan_hdd_set_akm_suite
11514 * This function is used to set the key mgmt type(PSK/8021x).
11515 *
11516 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011517static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011518 u32 key_mgmt
11519 )
11520{
11521 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11522 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053011523 /* Should be in ieee802_11_defs.h */
11524#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
11525#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070011526 /*set key mgmt type*/
11527 switch(key_mgmt)
11528 {
11529 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053011530 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011531#ifdef WLAN_FEATURE_VOWIFI_11R
11532 case WLAN_AKM_SUITE_FT_PSK:
11533#endif
11534 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070011535 __func__);
11536 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
11537 break;
11538
11539 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053011540 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011541#ifdef WLAN_FEATURE_VOWIFI_11R
11542 case WLAN_AKM_SUITE_FT_8021X:
11543#endif
11544 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070011545 __func__);
11546 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11547 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011548#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011549#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
11550#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
11551 case WLAN_AKM_SUITE_CCKM:
11552 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
11553 __func__);
11554 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
11555 break;
11556#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070011557#ifndef WLAN_AKM_SUITE_OSEN
11558#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
11559 case WLAN_AKM_SUITE_OSEN:
11560 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
11561 __func__);
11562 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11563 break;
11564#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011565
11566 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011567 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011568 __func__, key_mgmt);
11569 return -EINVAL;
11570
11571 }
11572 return 0;
11573}
11574
11575/*
11576 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011577 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070011578 * (NONE/WEP40/WEP104/TKIP/CCMP).
11579 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011580static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
11581 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070011582 bool ucast
11583 )
11584{
11585 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011586 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011587 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11588
11589 ENTER();
11590
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011591 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011592 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011593 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070011594 __func__, cipher);
11595 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11596 }
11597 else
11598 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011599
Jeff Johnson295189b2012-06-20 16:38:30 -070011600 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011601 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011602 {
11603 case IW_AUTH_CIPHER_NONE:
11604 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11605 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011606
Jeff Johnson295189b2012-06-20 16:38:30 -070011607 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011608 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070011609 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011610
Jeff Johnson295189b2012-06-20 16:38:30 -070011611 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011612 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070011613 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011614
Jeff Johnson295189b2012-06-20 16:38:30 -070011615 case WLAN_CIPHER_SUITE_TKIP:
11616 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
11617 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011618
Jeff Johnson295189b2012-06-20 16:38:30 -070011619 case WLAN_CIPHER_SUITE_CCMP:
11620 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11621 break;
11622#ifdef FEATURE_WLAN_WAPI
11623 case WLAN_CIPHER_SUITE_SMS4:
11624 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
11625 break;
11626#endif
11627
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011628#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011629 case WLAN_CIPHER_SUITE_KRK:
11630 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
11631 break;
11632#endif
11633 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011634 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011635 __func__, cipher);
11636 return -EOPNOTSUPP;
11637 }
11638 }
11639
11640 if (ucast)
11641 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011642 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011643 __func__, encryptionType);
11644 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11645 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011646 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011647 encryptionType;
11648 }
11649 else
11650 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011651 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011652 __func__, encryptionType);
11653 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
11654 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
11655 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
11656 }
11657
11658 return 0;
11659}
11660
11661
11662/*
11663 * FUNCTION: wlan_hdd_cfg80211_set_ie
11664 * This function is used to parse WPA/RSN IE's.
11665 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011666int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011667#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11668 const u8 *ie,
11669#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011670 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011671#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011672 size_t ie_len
11673 )
11674{
11675 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011676#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11677 const u8 *genie = ie;
11678#else
Jeff Johnson295189b2012-06-20 16:38:30 -070011679 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011680#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011681 v_U16_t remLen = ie_len;
11682#ifdef FEATURE_WLAN_WAPI
11683 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
11684 u16 *tmp;
11685 v_U16_t akmsuiteCount;
11686 int *akmlist;
11687#endif
11688 ENTER();
11689
11690 /* clear previous assocAddIE */
11691 pWextState->assocAddIE.length = 0;
11692 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011693 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011694
11695 while (remLen >= 2)
11696 {
11697 v_U16_t eLen = 0;
11698 v_U8_t elementId;
11699 elementId = *genie++;
11700 eLen = *genie++;
11701 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011702
Arif Hussain6d2a3322013-11-17 19:50:10 -080011703 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070011704 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011705
11706 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070011707 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011708 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011709 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 -070011710 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011711 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011712 "%s: Invalid WPA IE", __func__);
11713 return -EINVAL;
11714 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011715 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070011716 {
11717 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011718 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011719 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011720
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011721 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011722 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011723 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
11724 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011725 VOS_ASSERT(0);
11726 return -ENOMEM;
11727 }
11728 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11729 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11730 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011731
Jeff Johnson295189b2012-06-20 16:38:30 -070011732 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
11733 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11734 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11735 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011736 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
11737 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011738 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
11739 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11740 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
11741 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
11742 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
11743 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011744 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053011745 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011746 {
11747 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011748 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011749 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011750
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011751 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011752 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011753 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11754 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011755 VOS_ASSERT(0);
11756 return -ENOMEM;
11757 }
11758 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11759 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11760 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011761
Jeff Johnson295189b2012-06-20 16:38:30 -070011762 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11763 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11764 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011765#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011766 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
11767 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011768 /*Consider WFD IE, only for P2P Client */
11769 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11770 {
11771 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011772 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011773 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011774
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011775 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011776 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011777 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11778 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011779 VOS_ASSERT(0);
11780 return -ENOMEM;
11781 }
11782 // WFD IE is saved to Additional IE ; it should be accumulated to handle
11783 // WPS IE + P2P IE + WFD IE
11784 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11785 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011786
Jeff Johnson295189b2012-06-20 16:38:30 -070011787 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11788 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11789 }
11790#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011791 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011792 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011793 HS20_OUI_TYPE_SIZE)) )
11794 {
11795 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011796 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011797 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011798
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011799 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011800 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011801 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11802 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011803 VOS_ASSERT(0);
11804 return -ENOMEM;
11805 }
11806 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11807 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011808
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011809 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11810 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11811 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011812 /* Appending OSEN Information Element in Assiciation Request */
11813 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
11814 OSEN_OUI_TYPE_SIZE)) )
11815 {
11816 v_U16_t curAddIELen = pWextState->assocAddIE.length;
11817 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
11818 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011819
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011820 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011821 {
11822 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11823 "Need bigger buffer space");
11824 VOS_ASSERT(0);
11825 return -ENOMEM;
11826 }
11827 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11828 pWextState->assocAddIE.length += eLen + 2;
11829
11830 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
11831 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11832 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11833 }
11834
Abhishek Singh4322e622015-06-10 15:42:54 +053011835 /* Update only for WPA IE */
11836 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
11837 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070011838
11839 /* populating as ADDIE in beacon frames */
11840 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011841 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070011842 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
11843 {
11844 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11845 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
11846 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11847 {
11848 hddLog(LOGE,
11849 "Coldn't pass "
11850 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
11851 }
11852 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
11853 else
11854 hddLog(LOGE,
11855 "Could not pass on "
11856 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
11857
11858 /* IBSS mode doesn't contain params->proberesp_ies still
11859 beaconIE's need to be populated in probe response frames */
11860 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
11861 {
11862 u16 rem_probe_resp_ie_len = eLen + 2;
11863 u8 probe_rsp_ie_len[3] = {0};
11864 u8 counter = 0;
11865
11866 /* Check Probe Resp Length if it is greater then 255 then
11867 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
11868 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
11869 not able Store More then 255 bytes into One Variable */
11870
11871 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
11872 {
11873 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
11874 {
11875 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
11876 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
11877 }
11878 else
11879 {
11880 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
11881 rem_probe_resp_ie_len = 0;
11882 }
11883 }
11884
11885 rem_probe_resp_ie_len = 0;
11886
11887 if (probe_rsp_ie_len[0] > 0)
11888 {
11889 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11890 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
11891 (tANI_U8*)(genie - 2),
11892 probe_rsp_ie_len[0], NULL,
11893 eANI_BOOLEAN_FALSE)
11894 == eHAL_STATUS_FAILURE)
11895 {
11896 hddLog(LOGE,
11897 "Could not pass"
11898 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
11899 }
11900 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
11901 }
11902
11903 if (probe_rsp_ie_len[1] > 0)
11904 {
11905 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11906 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
11907 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11908 probe_rsp_ie_len[1], NULL,
11909 eANI_BOOLEAN_FALSE)
11910 == eHAL_STATUS_FAILURE)
11911 {
11912 hddLog(LOGE,
11913 "Could not pass"
11914 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
11915 }
11916 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
11917 }
11918
11919 if (probe_rsp_ie_len[2] > 0)
11920 {
11921 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11922 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
11923 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11924 probe_rsp_ie_len[2], NULL,
11925 eANI_BOOLEAN_FALSE)
11926 == eHAL_STATUS_FAILURE)
11927 {
11928 hddLog(LOGE,
11929 "Could not pass"
11930 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
11931 }
11932 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
11933 }
11934
11935 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11936 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
11937 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11938 {
11939 hddLog(LOGE,
11940 "Could not pass"
11941 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
11942 }
11943 }
11944 else
11945 {
11946 // Reset WNI_CFG_PROBE_RSP Flags
11947 wlan_hdd_reset_prob_rspies(pAdapter);
11948
11949 hddLog(VOS_TRACE_LEVEL_INFO,
11950 "%s: No Probe Response IE received in set beacon",
11951 __func__);
11952 }
11953 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070011954 break;
11955 case DOT11F_EID_RSN:
11956 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
11957 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11958 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
11959 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
11960 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
11961 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053011962
11963 /* Appending Extended Capabilities with Interworking bit set
11964 * in Assoc Req.
11965 *
11966 * In assoc req this EXT Cap will only be taken into account if
11967 * interworkingService bit is set to 1. Currently
11968 * driver is only interested in interworkingService capability
11969 * from supplicant. If in future any other EXT Cap info is
11970 * required from supplicat, it needs to be handled while
11971 * sending Assoc Req in LIM.
11972 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011973 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011974 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011975 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011976 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011977 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011978
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011979 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011980 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011981 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11982 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011983 VOS_ASSERT(0);
11984 return -ENOMEM;
11985 }
11986 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11987 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011988
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011989 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11990 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11991 break;
11992 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011993#ifdef FEATURE_WLAN_WAPI
11994 case WLAN_EID_WAPI:
11995 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011996 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011997 pAdapter->wapi_info.nWapiMode);
11998 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011999 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070012000 akmsuiteCount = WPA_GET_LE16(tmp);
12001 tmp = tmp + 1;
12002 akmlist = (int *)(tmp);
12003 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
12004 {
12005 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
12006 }
12007 else
12008 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012009 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070012010 VOS_ASSERT(0);
12011 return -EINVAL;
12012 }
12013
12014 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
12015 {
12016 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012017 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012018 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012019 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012020 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012021 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012022 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012023 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012024 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
12025 }
12026 break;
12027#endif
12028 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012029 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012030 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012031 /* when Unknown IE is received we should break and continue
12032 * to the next IE in the buffer instead we were returning
12033 * so changing this to break */
12034 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070012035 }
12036 genie += eLen;
12037 remLen -= eLen;
12038 }
12039 EXIT();
12040 return 0;
12041}
12042
12043/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012044 * FUNCTION: hdd_isWPAIEPresent
12045 * Parse the received IE to find the WPA IE
12046 *
12047 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012048static bool hdd_isWPAIEPresent(
12049#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
12050 const u8 *ie,
12051#else
12052 u8 *ie,
12053#endif
12054 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012055{
12056 v_U8_t eLen = 0;
12057 v_U16_t remLen = ie_len;
12058 v_U8_t elementId = 0;
12059
12060 while (remLen >= 2)
12061 {
12062 elementId = *ie++;
12063 eLen = *ie++;
12064 remLen -= 2;
12065 if (eLen > remLen)
12066 {
12067 hddLog(VOS_TRACE_LEVEL_ERROR,
12068 "%s: IE length is wrong %d", __func__, eLen);
12069 return FALSE;
12070 }
12071 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
12072 {
12073 /* OUI - 0x00 0X50 0XF2
12074 WPA Information Element - 0x01
12075 WPA version - 0x01*/
12076 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
12077 return TRUE;
12078 }
12079 ie += eLen;
12080 remLen -= eLen;
12081 }
12082 return FALSE;
12083}
12084
12085/*
Jeff Johnson295189b2012-06-20 16:38:30 -070012086 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012087 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012088 * parameters during connect operation.
12089 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012090int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012091 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012092 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012093{
12094 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012095 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012096 ENTER();
12097
12098 /*set wpa version*/
12099 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
12100
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012101 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012102 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053012103 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012104 {
12105 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12106 }
12107 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
12108 {
12109 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12110 }
12111 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012112
12113 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012114 pWextState->wpaVersion);
12115
12116 /*set authentication type*/
12117 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
12118
12119 if (0 > status)
12120 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012121 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012122 "%s: failed to set authentication type ", __func__);
12123 return status;
12124 }
12125
12126 /*set key mgmt type*/
12127 if (req->crypto.n_akm_suites)
12128 {
12129 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
12130 if (0 > status)
12131 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012132 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070012133 __func__);
12134 return status;
12135 }
12136 }
12137
12138 /*set pairwise cipher type*/
12139 if (req->crypto.n_ciphers_pairwise)
12140 {
12141 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
12142 req->crypto.ciphers_pairwise[0], true);
12143 if (0 > status)
12144 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012145 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012146 "%s: failed to set unicast cipher type", __func__);
12147 return status;
12148 }
12149 }
12150 else
12151 {
12152 /*Reset previous cipher suite to none*/
12153 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
12154 if (0 > status)
12155 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012156 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012157 "%s: failed to set unicast cipher type", __func__);
12158 return status;
12159 }
12160 }
12161
12162 /*set group cipher type*/
12163 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
12164 false);
12165
12166 if (0 > status)
12167 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012168 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070012169 __func__);
12170 return status;
12171 }
12172
Chet Lanctot186b5732013-03-18 10:26:30 -070012173#ifdef WLAN_FEATURE_11W
12174 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
12175#endif
12176
Jeff Johnson295189b2012-06-20 16:38:30 -070012177 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
12178 if (req->ie_len)
12179 {
12180 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
12181 if ( 0 > status)
12182 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012183 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012184 __func__);
12185 return status;
12186 }
12187 }
12188
12189 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012190 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012191 {
12192 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
12193 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
12194 )
12195 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012196 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070012197 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
12198 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012199 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012200 __func__);
12201 return -EOPNOTSUPP;
12202 }
12203 else
12204 {
12205 u8 key_len = req->key_len;
12206 u8 key_idx = req->key_idx;
12207
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012208 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012209 && (CSR_MAX_NUM_KEY > key_idx)
12210 )
12211 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012212 hddLog(VOS_TRACE_LEVEL_INFO,
12213 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012214 __func__, key_idx, key_len);
12215 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012216 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012217 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012218 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012219 (u8)key_len;
12220 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
12221 }
12222 }
12223 }
12224 }
12225
12226 return status;
12227}
12228
12229/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012230 * FUNCTION: wlan_hdd_try_disconnect
12231 * This function is used to disconnect from previous
12232 * connection
12233 */
12234static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
12235{
12236 long ret = 0;
12237 hdd_station_ctx_t *pHddStaCtx;
12238 eMib_dot11DesiredBssType connectedBssType;
12239
12240 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12241
12242 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
12243
12244 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
12245 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
12246 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
12247 {
12248 /* Issue disconnect to CSR */
12249 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12250 if( eHAL_STATUS_SUCCESS ==
12251 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12252 pAdapter->sessionId,
12253 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12254 {
12255 ret = wait_for_completion_interruptible_timeout(
12256 &pAdapter->disconnect_comp_var,
12257 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12258 if (0 >= ret)
12259 {
12260 hddLog(LOGE, FL("Failed to receive disconnect event"));
12261 return -EALREADY;
12262 }
12263 }
12264 }
12265 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
12266 {
12267 ret = wait_for_completion_interruptible_timeout(
12268 &pAdapter->disconnect_comp_var,
12269 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12270 if (0 >= ret)
12271 {
12272 hddLog(LOGE, FL("Failed to receive disconnect event"));
12273 return -EALREADY;
12274 }
12275 }
12276
12277 return 0;
12278}
12279
12280/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053012281 * FUNCTION: __wlan_hdd_cfg80211_connect
12282 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070012283 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012284static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012285 struct net_device *ndev,
12286 struct cfg80211_connect_params *req
12287 )
12288{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012289 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012290 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012291 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053012292 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012293
12294 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012295
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012296 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12297 TRACE_CODE_HDD_CFG80211_CONNECT,
12298 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012299 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012300 "%s: device_mode = %s (%d)", __func__,
12301 hdd_device_modetoString(pAdapter->device_mode),
12302 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012303
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012304 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012305 if (!pHddCtx)
12306 {
12307 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12308 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053012309 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012310 }
12311
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012312 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012313 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012314 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012315 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012316 }
12317
Agarwal Ashish51325b52014-06-16 16:50:49 +053012318 if (vos_max_concurrent_connections_reached()) {
12319 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12320 return -ECONNREFUSED;
12321 }
12322
Jeff Johnson295189b2012-06-20 16:38:30 -070012323#ifdef WLAN_BTAMP_FEATURE
12324 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012325 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070012326 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012327 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012328 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012329 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070012330 }
12331#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012332
12333 //If Device Mode is Station Concurrent Sessions Exit BMps
12334 //P2P Mode will be taken care in Open/close adapter
12335 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012336 (vos_concurrent_open_sessions_running())) {
12337 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
12338 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012339 }
12340
12341 /*Try disconnecting if already in connected state*/
12342 status = wlan_hdd_try_disconnect(pAdapter);
12343 if ( 0 > status)
12344 {
12345 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12346 " connection"));
12347 return -EALREADY;
12348 }
12349
Jeff Johnson295189b2012-06-20 16:38:30 -070012350 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012351 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070012352
12353 if ( 0 > status)
12354 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012355 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070012356 __func__);
12357 return status;
12358 }
Mohit Khanna765234a2012-09-11 15:08:35 -070012359 if ( req->channel )
12360 {
12361 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
12362 req->ssid_len, req->bssid,
12363 req->channel->hw_value);
12364 }
12365 else
12366 {
12367 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012368 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070012369 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012370
Sushant Kaushikd7083982015-03-18 14:33:24 +053012371 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012372 {
12373 //ReEnable BMPS if disabled
12374 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
12375 (NULL != pHddCtx))
12376 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012377 if (pHddCtx->hdd_wlan_suspended)
12378 {
12379 hdd_set_pwrparams(pHddCtx);
12380 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012381 //ReEnable Bmps and Imps back
12382 hdd_enable_bmps_imps(pHddCtx);
12383 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053012384 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070012385 return status;
12386 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012387 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012388 EXIT();
12389 return status;
12390}
12391
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012392static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
12393 struct net_device *ndev,
12394 struct cfg80211_connect_params *req)
12395{
12396 int ret;
12397 vos_ssr_protect(__func__);
12398 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
12399 vos_ssr_unprotect(__func__);
12400
12401 return ret;
12402}
Jeff Johnson295189b2012-06-20 16:38:30 -070012403
12404/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012405 * FUNCTION: wlan_hdd_disconnect
12406 * This function is used to issue a disconnect request to SME
12407 */
12408int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
12409{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012410 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012411 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012412 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012413 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012414
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012415 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012416
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012417 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012418 if (0 != status)
12419 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012420 return status;
12421 }
12422
Sushant Kaushikb4834d22015-07-15 15:29:05 +053012423 if (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)
12424 {
12425 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
12426 pAdapter->sessionId);
12427 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012428 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012429
Agarwal Ashish47d18112014-08-04 19:55:07 +053012430 /* Need to apply spin lock before decreasing active sessions
12431 * as there can be chance for double decrement if context switch
12432 * Calls hdd_DisConnectHandler.
12433 */
12434
12435 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012436 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
12437 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012438 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
12439 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053012440 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
12441 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012442
Abhishek Singhf4669da2014-05-26 15:07:49 +053012443 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053012444 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
12445
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012446 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012447
Mihir Shete182a0b22014-08-18 16:08:48 +053012448 /*
12449 * stop tx queues before deleting STA/BSS context from the firmware.
12450 * tx has to be disabled because the firmware can get busy dropping
12451 * the tx frames after BSS/STA has been deleted and will not send
12452 * back a response resulting in WDI timeout
12453 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053012454 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053012455 netif_tx_disable(pAdapter->dev);
12456 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012457
Mihir Shete182a0b22014-08-18 16:08:48 +053012458 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012459 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12460 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012461 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
12462 {
12463 hddLog(VOS_TRACE_LEVEL_INFO,
12464 FL("status = %d, already disconnected"),
12465 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012466
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012467 }
12468 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012469 {
12470 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012471 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012472 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012473 result = -EINVAL;
12474 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012475 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012476 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012477 &pAdapter->disconnect_comp_var,
12478 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012479 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012480 {
12481 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012482 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012483 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012484 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012485 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012486 {
12487 hddLog(VOS_TRACE_LEVEL_ERROR,
12488 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012489 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012490 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012491disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012492 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12493 FL("Set HDD connState to eConnectionState_NotConnected"));
12494 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
12495
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012496 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012497 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012498}
12499
12500
12501/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012502 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070012503 * This function is used to issue a disconnect request to SME
12504 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012505static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012506 struct net_device *dev,
12507 u16 reason
12508 )
12509{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012510 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012511 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012512 tCsrRoamProfile *pRoamProfile;
12513 hdd_station_ctx_t *pHddStaCtx;
12514 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012515#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012516 tANI_U8 staIdx;
12517#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012518
Jeff Johnson295189b2012-06-20 16:38:30 -070012519 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012520
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012521 if (!pAdapter) {
12522 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
12523 return -EINVAL;
12524 }
12525
12526 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12527 if (!pHddStaCtx) {
12528 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
12529 return -EINVAL;
12530 }
12531
12532 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12533 status = wlan_hdd_validate_context(pHddCtx);
12534 if (0 != status)
12535 {
12536 return status;
12537 }
12538
12539 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
12540
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012541 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12542 TRACE_CODE_HDD_CFG80211_DISCONNECT,
12543 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012544 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
12545 __func__, hdd_device_modetoString(pAdapter->device_mode),
12546 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012547
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012548 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
12549 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070012550
Jeff Johnson295189b2012-06-20 16:38:30 -070012551 if (NULL != pRoamProfile)
12552 {
12553 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012554 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
12555 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070012556 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012557 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070012558 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012559 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012560 switch(reason)
12561 {
12562 case WLAN_REASON_MIC_FAILURE:
12563 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
12564 break;
12565
12566 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
12567 case WLAN_REASON_DISASSOC_AP_BUSY:
12568 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
12569 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
12570 break;
12571
12572 case WLAN_REASON_PREV_AUTH_NOT_VALID:
12573 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053012574 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070012575 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
12576 break;
12577
Jeff Johnson295189b2012-06-20 16:38:30 -070012578 default:
12579 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
12580 break;
12581 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012582 pScanInfo = &pHddCtx->scan_info;
12583 if (pScanInfo->mScanPending)
12584 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012585 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012586 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012587 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012588 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012589 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012590
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012591#ifdef FEATURE_WLAN_TDLS
12592 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012593 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012594 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012595 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
12596 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012597 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012598 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012599 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012600 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012601 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012602 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012603 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012604 status = sme_DeleteTdlsPeerSta(
12605 WLAN_HDD_GET_HAL_CTX(pAdapter),
12606 pAdapter->sessionId,
12607 mac);
12608 if (status != eHAL_STATUS_SUCCESS) {
12609 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
12610 return -EPERM;
12611 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012612 }
12613 }
12614#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012615 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012616 status = wlan_hdd_disconnect(pAdapter, reasonCode);
12617 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070012618 {
12619 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012620 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012621 __func__, (int)status );
12622 return -EINVAL;
12623 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012624 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012625 else
12626 {
12627 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
12628 "called while in %d state", __func__,
12629 pHddStaCtx->conn_info.connState);
12630 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012631 }
12632 else
12633 {
12634 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
12635 }
12636
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012637 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012638 return status;
12639}
12640
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012641static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
12642 struct net_device *dev,
12643 u16 reason
12644 )
12645{
12646 int ret;
12647 vos_ssr_protect(__func__);
12648 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
12649 vos_ssr_unprotect(__func__);
12650
12651 return ret;
12652}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012653
Jeff Johnson295189b2012-06-20 16:38:30 -070012654/*
12655 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012656 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012657 * settings in IBSS mode.
12658 */
12659static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012660 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012661 struct cfg80211_ibss_params *params
12662 )
12663{
12664 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012665 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012666 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12667 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012668
Jeff Johnson295189b2012-06-20 16:38:30 -070012669 ENTER();
12670
12671 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070012672 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070012673
12674 if (params->ie_len && ( NULL != params->ie) )
12675 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012676 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12677 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012678 {
12679 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12680 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12681 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012682 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012683 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012684 tDot11fIEWPA dot11WPAIE;
12685 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012686 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012687
Wilson Yang00256342013-10-10 23:13:38 -070012688 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012689 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12690 params->ie_len, DOT11F_EID_WPA);
12691 if ( NULL != ie )
12692 {
12693 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12694 // Unpack the WPA IE
12695 //Skip past the EID byte and length byte - and four byte WiFi OUI
12696 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
12697 &ie[2+4],
12698 ie[1] - 4,
12699 &dot11WPAIE);
12700 /*Extract the multicast cipher, the encType for unicast
12701 cipher for wpa-none is none*/
12702 encryptionType =
12703 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
12704 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012705 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012706
Jeff Johnson295189b2012-06-20 16:38:30 -070012707 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
12708
12709 if (0 > status)
12710 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012711 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012712 __func__);
12713 return status;
12714 }
12715 }
12716
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012717 pWextState->roamProfile.AuthType.authType[0] =
12718 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012719 eCSR_AUTH_TYPE_OPEN_SYSTEM;
12720
12721 if (params->privacy)
12722 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012723 /* Security enabled IBSS, At this time there is no information available
12724 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070012725 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012726 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070012727 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012728 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070012729 *enable privacy bit in beacons */
12730
12731 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12732 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012733 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
12734 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070012735 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12736 pWextState->roamProfile.EncryptionType.numEntries = 1;
12737 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070012738 return status;
12739}
12740
12741/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012742 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012743 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012744 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012745static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012746 struct net_device *dev,
12747 struct cfg80211_ibss_params *params
12748 )
12749{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012750 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012751 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12752 tCsrRoamProfile *pRoamProfile;
12753 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012754 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12755 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012756 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070012757
12758 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012759
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012760 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12761 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
12762 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012763 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012764 "%s: device_mode = %s (%d)", __func__,
12765 hdd_device_modetoString(pAdapter->device_mode),
12766 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012767
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012768 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012769 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012770 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012771 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012772 }
12773
12774 if (NULL == pWextState)
12775 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012776 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012777 __func__);
12778 return -EIO;
12779 }
12780
Agarwal Ashish51325b52014-06-16 16:50:49 +053012781 if (vos_max_concurrent_connections_reached()) {
12782 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12783 return -ECONNREFUSED;
12784 }
12785
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012786 /*Try disconnecting if already in connected state*/
12787 status = wlan_hdd_try_disconnect(pAdapter);
12788 if ( 0 > status)
12789 {
12790 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12791 " IBSS connection"));
12792 return -EALREADY;
12793 }
12794
Jeff Johnson295189b2012-06-20 16:38:30 -070012795 pRoamProfile = &pWextState->roamProfile;
12796
12797 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
12798 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012799 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012800 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012801 return -EINVAL;
12802 }
12803
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012804 /* BSSID is provided by upper layers hence no need to AUTO generate */
12805 if (NULL != params->bssid) {
12806 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12807 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
12808 hddLog (VOS_TRACE_LEVEL_ERROR,
12809 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12810 return -EIO;
12811 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012812 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012813 }
krunal sonie9002db2013-11-25 14:24:17 -080012814 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
12815 {
12816 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12817 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
12818 {
12819 hddLog (VOS_TRACE_LEVEL_ERROR,
12820 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12821 return -EIO;
12822 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012823
12824 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080012825 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012826 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080012827 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012828
Jeff Johnson295189b2012-06-20 16:38:30 -070012829 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070012830 if (NULL !=
12831#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12832 params->chandef.chan)
12833#else
12834 params->channel)
12835#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012836 {
12837 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012838 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12839 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
12840 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12841 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012842
12843 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012844 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070012845 ieee80211_frequency_to_channel(
12846#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12847 params->chandef.chan->center_freq);
12848#else
12849 params->channel->center_freq);
12850#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012851
12852 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12853 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070012854 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012855 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
12856 __func__);
12857 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070012858 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012859
12860 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012861 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012862 if (channelNum == validChan[indx])
12863 {
12864 break;
12865 }
12866 }
12867 if (indx >= numChans)
12868 {
12869 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012870 __func__, channelNum);
12871 return -EINVAL;
12872 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012873 /* Set the Operational Channel */
12874 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
12875 channelNum);
12876 pRoamProfile->ChannelInfo.numOfChannels = 1;
12877 pHddStaCtx->conn_info.operationChannel = channelNum;
12878 pRoamProfile->ChannelInfo.ChannelList =
12879 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070012880 }
12881
12882 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012883 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070012884 if (status < 0)
12885 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012886 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070012887 __func__);
12888 return status;
12889 }
12890
12891 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012892 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012893 params->ssid_len, params->bssid,
12894 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070012895
12896 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012897 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012898
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012899 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012900 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012901}
12902
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012903static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
12904 struct net_device *dev,
12905 struct cfg80211_ibss_params *params
12906 )
12907{
12908 int ret = 0;
12909
12910 vos_ssr_protect(__func__);
12911 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
12912 vos_ssr_unprotect(__func__);
12913
12914 return ret;
12915}
12916
Jeff Johnson295189b2012-06-20 16:38:30 -070012917/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012918 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012919 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012920 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012921static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012922 struct net_device *dev
12923 )
12924{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012925 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012926 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12927 tCsrRoamProfile *pRoamProfile;
12928 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012929 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012930
12931 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012932
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012933 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12934 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
12935 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012936 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012937 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012938 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012939 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012940 }
12941
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012942 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
12943 hdd_device_modetoString(pAdapter->device_mode),
12944 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012945 if (NULL == pWextState)
12946 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012947 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012948 __func__);
12949 return -EIO;
12950 }
12951
12952 pRoamProfile = &pWextState->roamProfile;
12953
12954 /* Issue disconnect only if interface type is set to IBSS */
12955 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
12956 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012957 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070012958 __func__);
12959 return -EINVAL;
12960 }
12961
12962 /* Issue Disconnect request */
12963 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12964 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12965 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
12966
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012967 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012968 return 0;
12969}
12970
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012971static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
12972 struct net_device *dev
12973 )
12974{
12975 int ret = 0;
12976
12977 vos_ssr_protect(__func__);
12978 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
12979 vos_ssr_unprotect(__func__);
12980
12981 return ret;
12982}
12983
Jeff Johnson295189b2012-06-20 16:38:30 -070012984/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012985 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070012986 * This function is used to set the phy parameters
12987 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
12988 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012989static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012990 u32 changed)
12991{
12992 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
12993 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012994 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012995
12996 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012997
12998 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012999 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
13000 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013001
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013002 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013003 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013004 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013005 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013006 }
13007
Jeff Johnson295189b2012-06-20 16:38:30 -070013008 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
13009 {
13010 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
13011 WNI_CFG_RTS_THRESHOLD_STAMAX :
13012 wiphy->rts_threshold;
13013
13014 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013015 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070013016 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013017 hddLog(VOS_TRACE_LEVEL_ERROR,
13018 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013019 __func__, rts_threshold);
13020 return -EINVAL;
13021 }
13022
13023 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
13024 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013025 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013026 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013027 hddLog(VOS_TRACE_LEVEL_ERROR,
13028 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013029 __func__, rts_threshold);
13030 return -EIO;
13031 }
13032
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013033 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013034 rts_threshold);
13035 }
13036
13037 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
13038 {
13039 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
13040 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
13041 wiphy->frag_threshold;
13042
13043 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013044 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013045 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013046 hddLog(VOS_TRACE_LEVEL_ERROR,
13047 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013048 frag_threshold);
13049 return -EINVAL;
13050 }
13051
13052 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
13053 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013054 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013055 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013056 hddLog(VOS_TRACE_LEVEL_ERROR,
13057 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013058 __func__, frag_threshold);
13059 return -EIO;
13060 }
13061
13062 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
13063 frag_threshold);
13064 }
13065
13066 if ((changed & WIPHY_PARAM_RETRY_SHORT)
13067 || (changed & WIPHY_PARAM_RETRY_LONG))
13068 {
13069 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
13070 wiphy->retry_short :
13071 wiphy->retry_long;
13072
13073 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
13074 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
13075 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013076 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013077 __func__, retry_value);
13078 return -EINVAL;
13079 }
13080
13081 if (changed & WIPHY_PARAM_RETRY_SHORT)
13082 {
13083 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
13084 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013085 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013086 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013087 hddLog(VOS_TRACE_LEVEL_ERROR,
13088 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013089 __func__, retry_value);
13090 return -EIO;
13091 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013092 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013093 __func__, retry_value);
13094 }
13095 else if (changed & WIPHY_PARAM_RETRY_SHORT)
13096 {
13097 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
13098 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013099 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013100 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013101 hddLog(VOS_TRACE_LEVEL_ERROR,
13102 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013103 __func__, retry_value);
13104 return -EIO;
13105 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013106 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013107 __func__, retry_value);
13108 }
13109 }
13110
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013111 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013112 return 0;
13113}
13114
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013115static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
13116 u32 changed)
13117{
13118 int ret;
13119
13120 vos_ssr_protect(__func__);
13121 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
13122 vos_ssr_unprotect(__func__);
13123
13124 return ret;
13125}
13126
Jeff Johnson295189b2012-06-20 16:38:30 -070013127/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013128 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013129 * This function is used to set the txpower
13130 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013131static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013132#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13133 struct wireless_dev *wdev,
13134#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013135#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013136 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013137#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013138 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013139#endif
13140 int dbm)
13141{
13142 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013143 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013144 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13145 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013146 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013147
13148 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013149
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013150 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13151 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
13152 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013153 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013154 if (0 != status)
13155 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013156 return status;
13157 }
13158
13159 hHal = pHddCtx->hHal;
13160
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013161 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
13162 dbm, ccmCfgSetCallback,
13163 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013164 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013165 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013166 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
13167 return -EIO;
13168 }
13169
13170 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
13171 dbm);
13172
13173 switch(type)
13174 {
13175 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
13176 /* Fall through */
13177 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
13178 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
13179 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013180 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
13181 __func__);
13182 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013183 }
13184 break;
13185 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013186 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070013187 __func__);
13188 return -EOPNOTSUPP;
13189 break;
13190 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013191 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
13192 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070013193 return -EIO;
13194 }
13195
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013196 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013197 return 0;
13198}
13199
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013200static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
13201#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13202 struct wireless_dev *wdev,
13203#endif
13204#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13205 enum tx_power_setting type,
13206#else
13207 enum nl80211_tx_power_setting type,
13208#endif
13209 int dbm)
13210{
13211 int ret;
13212 vos_ssr_protect(__func__);
13213 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
13214#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13215 wdev,
13216#endif
13217#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13218 type,
13219#else
13220 type,
13221#endif
13222 dbm);
13223 vos_ssr_unprotect(__func__);
13224
13225 return ret;
13226}
13227
Jeff Johnson295189b2012-06-20 16:38:30 -070013228/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013229 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013230 * This function is used to read the txpower
13231 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013232static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013233#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13234 struct wireless_dev *wdev,
13235#endif
13236 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070013237{
13238
13239 hdd_adapter_t *pAdapter;
13240 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013241 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013242
Jeff Johnsone7245742012-09-05 17:12:55 -070013243 ENTER();
13244
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013245 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013246 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013247 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013248 *dbm = 0;
13249 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013250 }
13251
Jeff Johnson295189b2012-06-20 16:38:30 -070013252 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
13253 if (NULL == pAdapter)
13254 {
13255 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
13256 return -ENOENT;
13257 }
13258
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053013259 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13260 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
13261 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070013262 wlan_hdd_get_classAstats(pAdapter);
13263 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
13264
Jeff Johnsone7245742012-09-05 17:12:55 -070013265 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013266 return 0;
13267}
13268
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013269static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
13270#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13271 struct wireless_dev *wdev,
13272#endif
13273 int *dbm)
13274{
13275 int ret;
13276
13277 vos_ssr_protect(__func__);
13278 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
13279#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13280 wdev,
13281#endif
13282 dbm);
13283 vos_ssr_unprotect(__func__);
13284
13285 return ret;
13286}
13287
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013288static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013289#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13290 const u8* mac,
13291#else
13292 u8* mac,
13293#endif
13294 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070013295{
13296 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13297 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13298 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053013299 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070013300
13301 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
13302 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070013303
13304 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
13305 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
13306 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
13307 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
13308 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
13309 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
13310 tANI_U16 maxRate = 0;
13311 tANI_U16 myRate;
13312 tANI_U16 currentRate = 0;
13313 tANI_U8 maxSpeedMCS = 0;
13314 tANI_U8 maxMCSIdx = 0;
13315 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053013316 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013317 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013318 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013319
Leo Chang6f8870f2013-03-26 18:11:36 -070013320#ifdef WLAN_FEATURE_11AC
13321 tANI_U32 vht_mcs_map;
13322 eDataRate11ACMaxMcs vhtMaxMcs;
13323#endif /* WLAN_FEATURE_11AC */
13324
Jeff Johnsone7245742012-09-05 17:12:55 -070013325 ENTER();
13326
Jeff Johnson295189b2012-06-20 16:38:30 -070013327 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
13328 (0 == ssidlen))
13329 {
13330 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
13331 " Invalid ssidlen, %d", __func__, ssidlen);
13332 /*To keep GUI happy*/
13333 return 0;
13334 }
13335
Mukul Sharma811205f2014-07-09 21:07:30 +053013336 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
13337 {
13338 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13339 "%s: Roaming in progress, so unable to proceed this request", __func__);
13340 return 0;
13341 }
13342
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013343 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013344 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013345 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013346 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013347 }
13348
Jeff Johnson295189b2012-06-20 16:38:30 -070013349
Kiet Lam3b17fc82013-09-27 05:24:08 +053013350 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
13351 sinfo->filled |= STATION_INFO_SIGNAL;
13352
c_hpothu09f19542014-05-30 21:53:31 +053013353 wlan_hdd_get_station_stats(pAdapter);
13354 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
13355
13356 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053013357 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
13358 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053013359 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053013360 {
13361 rate_flags = pAdapter->maxRateFlags;
13362 }
c_hpothu44ff4e02014-05-08 00:13:57 +053013363
Jeff Johnson295189b2012-06-20 16:38:30 -070013364 //convert to the UI units of 100kbps
13365 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
13366
13367#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070013368 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 -070013369 sinfo->signal,
13370 pCfg->reportMaxLinkSpeed,
13371 myRate,
13372 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013373 (int) pCfg->linkSpeedRssiMid,
13374 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070013375 (int) rate_flags,
13376 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013377#endif //LINKSPEED_DEBUG_ENABLED
13378
13379 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
13380 {
13381 // we do not want to necessarily report the current speed
13382 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
13383 {
13384 // report the max possible speed
13385 rssidx = 0;
13386 }
13387 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
13388 {
13389 // report the max possible speed with RSSI scaling
13390 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
13391 {
13392 // report the max possible speed
13393 rssidx = 0;
13394 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013395 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070013396 {
13397 // report middle speed
13398 rssidx = 1;
13399 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013400 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
13401 {
13402 // report middle speed
13403 rssidx = 2;
13404 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013405 else
13406 {
13407 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013408 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070013409 }
13410 }
13411 else
13412 {
13413 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
13414 hddLog(VOS_TRACE_LEVEL_ERROR,
13415 "%s: Invalid value for reportMaxLinkSpeed: %u",
13416 __func__, pCfg->reportMaxLinkSpeed);
13417 rssidx = 0;
13418 }
13419
13420 maxRate = 0;
13421
13422 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013423 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
13424 OperationalRates, &ORLeng))
13425 {
13426 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13427 /*To keep GUI happy*/
13428 return 0;
13429 }
13430
Jeff Johnson295189b2012-06-20 16:38:30 -070013431 for (i = 0; i < ORLeng; i++)
13432 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013433 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013434 {
13435 /* Validate Rate Set */
13436 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
13437 {
13438 currentRate = supported_data_rate[j].supported_rate[rssidx];
13439 break;
13440 }
13441 }
13442 /* Update MAX rate */
13443 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13444 }
13445
13446 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013447 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
13448 ExtendedRates, &ERLeng))
13449 {
13450 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13451 /*To keep GUI happy*/
13452 return 0;
13453 }
13454
Jeff Johnson295189b2012-06-20 16:38:30 -070013455 for (i = 0; i < ERLeng; i++)
13456 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013457 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013458 {
13459 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
13460 {
13461 currentRate = supported_data_rate[j].supported_rate[rssidx];
13462 break;
13463 }
13464 }
13465 /* Update MAX rate */
13466 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13467 }
c_hpothu79aab322014-07-14 21:11:01 +053013468
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013469 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053013470 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013471 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053013472 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070013473 {
c_hpothu79aab322014-07-14 21:11:01 +053013474 if (rate_flags & eHAL_TX_RATE_VHT80)
13475 mode = 2;
13476 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
13477 mode = 1;
13478 else
13479 mode = 0;
13480
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013481 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
13482 MCSRates, &MCSLeng))
13483 {
13484 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13485 /*To keep GUI happy*/
13486 return 0;
13487 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013488 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070013489#ifdef WLAN_FEATURE_11AC
13490 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013491 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070013492 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013493 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013494 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070013495 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070013496 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013497 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013498 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013499 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070013500 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013501 maxMCSIdx = 7;
13502 }
13503 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
13504 {
13505 maxMCSIdx = 8;
13506 }
13507 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
13508 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013509 //VHT20 is supporting 0~8
13510 if (rate_flags & eHAL_TX_RATE_VHT20)
13511 maxMCSIdx = 8;
13512 else
13513 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070013514 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013515
c_hpothu79aab322014-07-14 21:11:01 +053013516 if (0 != rssidx)/*check for scaled */
13517 {
13518 //get middle rate MCS index if rssi=1/2
13519 for (i=0; i <= maxMCSIdx; i++)
13520 {
13521 if (sinfo->signal <= rssiMcsTbl[mode][i])
13522 {
13523 maxMCSIdx = i;
13524 break;
13525 }
13526 }
13527 }
13528
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013529 if (rate_flags & eHAL_TX_RATE_VHT80)
13530 {
13531 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
13532 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
13533 }
13534 else if (rate_flags & eHAL_TX_RATE_VHT40)
13535 {
13536 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
13537 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
13538 }
13539 else if (rate_flags & eHAL_TX_RATE_VHT20)
13540 {
13541 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
13542 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
13543 }
13544
Leo Chang6f8870f2013-03-26 18:11:36 -070013545 maxSpeedMCS = 1;
13546 if (currentRate > maxRate)
13547 {
13548 maxRate = currentRate;
13549 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013550
Leo Chang6f8870f2013-03-26 18:11:36 -070013551 }
13552 else
13553#endif /* WLAN_FEATURE_11AC */
13554 {
13555 if (rate_flags & eHAL_TX_RATE_HT40)
13556 {
13557 rateFlag |= 1;
13558 }
13559 if (rate_flags & eHAL_TX_RATE_SGI)
13560 {
13561 rateFlag |= 2;
13562 }
13563
Girish Gowli01abcee2014-07-31 20:18:55 +053013564 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053013565 if (rssidx == 1 || rssidx == 2)
13566 {
13567 //get middle rate MCS index if rssi=1/2
13568 for (i=0; i <= 7; i++)
13569 {
13570 if (sinfo->signal <= rssiMcsTbl[mode][i])
13571 {
13572 temp = i+1;
13573 break;
13574 }
13575 }
13576 }
c_hpothu79aab322014-07-14 21:11:01 +053013577
13578 for (i = 0; i < MCSLeng; i++)
13579 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013580 for (j = 0; j < temp; j++)
13581 {
13582 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
13583 {
13584 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053013585 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013586 break;
13587 }
13588 }
13589 if ((j < temp) && (currentRate > maxRate))
13590 {
13591 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070013592 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013593 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053013594 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013595 }
13596 }
13597
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013598 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
13599 {
13600 maxRate = myRate;
13601 maxSpeedMCS = 1;
13602 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13603 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013604 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053013605 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070013606 {
13607 maxRate = myRate;
13608 if (rate_flags & eHAL_TX_RATE_LEGACY)
13609 {
13610 maxSpeedMCS = 0;
13611 }
13612 else
13613 {
13614 maxSpeedMCS = 1;
13615 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13616 }
13617 }
13618
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013619 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070013620 {
13621 sinfo->txrate.legacy = maxRate;
13622#ifdef LINKSPEED_DEBUG_ENABLED
13623 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
13624#endif //LINKSPEED_DEBUG_ENABLED
13625 }
13626 else
13627 {
13628 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070013629#ifdef WLAN_FEATURE_11AC
13630 sinfo->txrate.nss = 1;
13631 if (rate_flags & eHAL_TX_RATE_VHT80)
13632 {
13633 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013634 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070013635 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013636 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070013637 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013638 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13639 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13640 }
13641 else if (rate_flags & eHAL_TX_RATE_VHT20)
13642 {
13643 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13644 }
13645#endif /* WLAN_FEATURE_11AC */
13646 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
13647 {
13648 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13649 if (rate_flags & eHAL_TX_RATE_HT40)
13650 {
13651 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13652 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013653 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013654 if (rate_flags & eHAL_TX_RATE_SGI)
13655 {
13656 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13657 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013658
Jeff Johnson295189b2012-06-20 16:38:30 -070013659#ifdef LINKSPEED_DEBUG_ENABLED
13660 pr_info("Reporting MCS rate %d flags %x\n",
13661 sinfo->txrate.mcs,
13662 sinfo->txrate.flags );
13663#endif //LINKSPEED_DEBUG_ENABLED
13664 }
13665 }
13666 else
13667 {
13668 // report current rate instead of max rate
13669
13670 if (rate_flags & eHAL_TX_RATE_LEGACY)
13671 {
13672 //provide to the UI in units of 100kbps
13673 sinfo->txrate.legacy = myRate;
13674#ifdef LINKSPEED_DEBUG_ENABLED
13675 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
13676#endif //LINKSPEED_DEBUG_ENABLED
13677 }
13678 else
13679 {
13680 //must be MCS
13681 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013682#ifdef WLAN_FEATURE_11AC
13683 sinfo->txrate.nss = 1;
13684 if (rate_flags & eHAL_TX_RATE_VHT80)
13685 {
13686 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13687 }
13688 else
13689#endif /* WLAN_FEATURE_11AC */
13690 {
13691 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13692 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013693 if (rate_flags & eHAL_TX_RATE_SGI)
13694 {
13695 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13696 }
13697 if (rate_flags & eHAL_TX_RATE_HT40)
13698 {
13699 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13700 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013701#ifdef WLAN_FEATURE_11AC
13702 else if (rate_flags & eHAL_TX_RATE_VHT80)
13703 {
13704 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
13705 }
13706#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070013707#ifdef LINKSPEED_DEBUG_ENABLED
13708 pr_info("Reporting actual MCS rate %d flags %x\n",
13709 sinfo->txrate.mcs,
13710 sinfo->txrate.flags );
13711#endif //LINKSPEED_DEBUG_ENABLED
13712 }
13713 }
13714 sinfo->filled |= STATION_INFO_TX_BITRATE;
13715
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013716 sinfo->tx_packets =
13717 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
13718 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
13719 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
13720 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
13721
13722 sinfo->tx_retries =
13723 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
13724 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
13725 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
13726 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
13727
13728 sinfo->tx_failed =
13729 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
13730 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
13731 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
13732 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
13733
13734 sinfo->filled |=
13735 STATION_INFO_TX_PACKETS |
13736 STATION_INFO_TX_RETRIES |
13737 STATION_INFO_TX_FAILED;
13738
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013739 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13740 TRACE_CODE_HDD_CFG80211_GET_STA,
13741 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013742 EXIT();
13743 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013744}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013745#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13746static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
13747 const u8* mac, struct station_info *sinfo)
13748#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013749static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
13750 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013751#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013752{
13753 int ret;
13754
13755 vos_ssr_protect(__func__);
13756 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
13757 vos_ssr_unprotect(__func__);
13758
13759 return ret;
13760}
13761
13762static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070013763 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070013764{
13765 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013766 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013767 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013768 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013769
Jeff Johnsone7245742012-09-05 17:12:55 -070013770 ENTER();
13771
Jeff Johnson295189b2012-06-20 16:38:30 -070013772 if (NULL == pAdapter)
13773 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013774 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013775 return -ENODEV;
13776 }
13777
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013778 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13779 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
13780 pAdapter->sessionId, timeout));
13781
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013782 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013783 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013784 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013785 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013786 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013787 }
13788
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013789 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
13790 (TRUE == pHddCtx->hdd_wlan_suspended) &&
13791 (pHddCtx->cfg_ini->fhostArpOffload) &&
13792 (eConnectionState_Associated ==
13793 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13794 {
Amar Singhald53568e2013-09-26 11:03:45 -070013795
13796 hddLog(VOS_TRACE_LEVEL_INFO,
13797 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053013798 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013799 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13800 {
13801 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013802 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013803 __func__, vos_status);
13804 }
13805 }
13806
Jeff Johnson295189b2012-06-20 16:38:30 -070013807 /**The get power cmd from the supplicant gets updated by the nl only
13808 *on successful execution of the function call
13809 *we are oppositely mapped w.r.t mode in the driver
13810 **/
13811 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
13812
13813 if (VOS_STATUS_E_FAILURE == vos_status)
13814 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013815 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13816 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013817 return -EINVAL;
13818 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013819 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013820 return 0;
13821}
13822
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013823static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
13824 struct net_device *dev, bool mode, int timeout)
13825{
13826 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013827
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013828 vos_ssr_protect(__func__);
13829 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
13830 vos_ssr_unprotect(__func__);
13831
13832 return ret;
13833}
Jeff Johnson295189b2012-06-20 16:38:30 -070013834#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013835static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
13836 struct net_device *netdev,
13837 u8 key_index)
13838{
13839 ENTER();
13840 return 0;
13841}
13842
Jeff Johnson295189b2012-06-20 16:38:30 -070013843static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013844 struct net_device *netdev,
13845 u8 key_index)
13846{
13847 int ret;
13848 vos_ssr_protect(__func__);
13849 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
13850 vos_ssr_unprotect(__func__);
13851 return ret;
13852}
13853#endif //LINUX_VERSION_CODE
13854
13855#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13856static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13857 struct net_device *dev,
13858 struct ieee80211_txq_params *params)
13859{
13860 ENTER();
13861 return 0;
13862}
13863#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13864static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13865 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013866{
Jeff Johnsone7245742012-09-05 17:12:55 -070013867 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013868 return 0;
13869}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013870#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070013871
13872#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13873static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013874 struct net_device *dev,
13875 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013876{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013877 int ret;
13878
13879 vos_ssr_protect(__func__);
13880 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
13881 vos_ssr_unprotect(__func__);
13882 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013883}
13884#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13885static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
13886 struct ieee80211_txq_params *params)
13887{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013888 int ret;
13889
13890 vos_ssr_protect(__func__);
13891 ret = __wlan_hdd_set_txq_params(wiphy, params);
13892 vos_ssr_unprotect(__func__);
13893 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013894}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013895#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013896
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013897static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013898 struct net_device *dev,
13899 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070013900{
13901 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013902 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013903 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013904 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013905 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013906 v_CONTEXT_t pVosContext = NULL;
13907 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013908
Jeff Johnsone7245742012-09-05 17:12:55 -070013909 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013910
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013911 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070013912 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013913 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013914 return -EINVAL;
13915 }
13916
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013917 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13918 TRACE_CODE_HDD_CFG80211_DEL_STA,
13919 pAdapter->sessionId, pAdapter->device_mode));
13920
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013921 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13922 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013923 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013924 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013925 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013926 }
13927
Jeff Johnson295189b2012-06-20 16:38:30 -070013928 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013929 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013930 )
13931 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013932 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13933 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13934 if(pSapCtx == NULL){
13935 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13936 FL("psapCtx is NULL"));
13937 return -ENOENT;
13938 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013939 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013940 {
13941 v_U16_t i;
13942 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
13943 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013944 if ((pSapCtx->aStaInfo[i].isUsed) &&
13945 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070013946 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013947 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013948 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013949 ETHER_ADDR_LEN);
13950
Jeff Johnson295189b2012-06-20 16:38:30 -070013951 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013952 "%s: Delete STA with MAC::"
13953 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013954 __func__,
13955 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
13956 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070013957 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013958 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013959 }
13960 }
13961 }
13962 else
13963 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013964
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013965 vos_status = hdd_softap_GetStaId(pAdapter,
13966 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013967 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13968 {
13969 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013970 "%s: Skip this DEL STA as this is not used::"
13971 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013972 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013973 return -ENOENT;
13974 }
13975
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013976 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013977 {
13978 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013979 "%s: Skip this DEL STA as deauth is in progress::"
13980 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013981 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013982 return -ENOENT;
13983 }
13984
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013985 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013986
Jeff Johnson295189b2012-06-20 16:38:30 -070013987 hddLog(VOS_TRACE_LEVEL_INFO,
13988 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013989 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013990 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013991 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013992
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013993 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013994 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13995 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013996 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013997 hddLog(VOS_TRACE_LEVEL_INFO,
13998 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013999 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014000 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014001 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014002 return -ENOENT;
14003 }
14004
Jeff Johnson295189b2012-06-20 16:38:30 -070014005 }
14006 }
14007
14008 EXIT();
14009
14010 return 0;
14011}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014012
14013#ifdef CFG80211_DEL_STA_V2
14014static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14015 struct net_device *dev,
14016 struct station_del_parameters *param)
14017#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014018#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14019static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14020 struct net_device *dev, const u8 *mac)
14021#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014022static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14023 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014024#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014025#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014026{
14027 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014028 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070014029
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014030 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014031
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014032#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014033 if (NULL == param) {
14034 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014035 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014036 return -EINVAL;
14037 }
14038
14039 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
14040 param->subtype, &delStaParams);
14041
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014042#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053014043 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014044 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014045#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014046 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
14047
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014048 vos_ssr_unprotect(__func__);
14049
14050 return ret;
14051}
14052
14053static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014054 struct net_device *dev,
14055#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14056 const u8 *mac,
14057#else
14058 u8 *mac,
14059#endif
14060 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014061{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014062 hdd_adapter_t *pAdapter;
14063 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014064 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014065#ifdef FEATURE_WLAN_TDLS
14066 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014067
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014068 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014069
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014070 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14071 if (NULL == pAdapter)
14072 {
14073 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14074 "%s: Adapter is NULL",__func__);
14075 return -EINVAL;
14076 }
14077 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14078 status = wlan_hdd_validate_context(pHddCtx);
14079 if (0 != status)
14080 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014081 return status;
14082 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014083
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014084 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14085 TRACE_CODE_HDD_CFG80211_ADD_STA,
14086 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014087 mask = params->sta_flags_mask;
14088
14089 set = params->sta_flags_set;
14090
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014091 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014092 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
14093 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014094
14095 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
14096 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014097 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014098 }
14099 }
14100#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014101 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014102 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014103}
14104
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014105#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14106static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14107 struct net_device *dev, const u8 *mac,
14108 struct station_parameters *params)
14109#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014110static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14111 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014112#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014113{
14114 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014115
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014116 vos_ssr_protect(__func__);
14117 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
14118 vos_ssr_unprotect(__func__);
14119
14120 return ret;
14121}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014122#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070014123
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014124static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070014125 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014126{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014127 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14128 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014129 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014130 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014131 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014132 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070014133
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014134 ENTER();
14135
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014136 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014137 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014138 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014139 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014140 return -EINVAL;
14141 }
14142
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014143 if (!pmksa) {
14144 hddLog(LOGE, FL("pmksa is NULL"));
14145 return -EINVAL;
14146 }
14147
14148 if (!pmksa->bssid || !pmksa->pmkid) {
14149 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
14150 pmksa->bssid, pmksa->pmkid);
14151 return -EINVAL;
14152 }
14153
14154 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
14155 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14156
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014157 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14158 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014159 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014160 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014161 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014162 }
14163
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014164 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014165 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14166
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014167 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
14168 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014169
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014170 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014171 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014172 &pmk_id, 1, FALSE);
14173
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014174 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14175 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
14176 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014177
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014178 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014179 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014180}
14181
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014182static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
14183 struct cfg80211_pmksa *pmksa)
14184{
14185 int ret;
14186
14187 vos_ssr_protect(__func__);
14188 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
14189 vos_ssr_unprotect(__func__);
14190
14191 return ret;
14192}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014193
Wilson Yang6507c4e2013-10-01 20:11:19 -070014194
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014195static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070014196 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014197{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014198 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14199 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014200 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014201 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014202
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014203 ENTER();
14204
Wilson Yang6507c4e2013-10-01 20:11:19 -070014205 /* Validate pAdapter */
14206 if (NULL == pAdapter)
14207 {
14208 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
14209 return -EINVAL;
14210 }
14211
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014212 if (!pmksa) {
14213 hddLog(LOGE, FL("pmksa is NULL"));
14214 return -EINVAL;
14215 }
14216
14217 if (!pmksa->bssid) {
14218 hddLog(LOGE, FL("pmksa->bssid is NULL"));
14219 return -EINVAL;
14220 }
14221
Kiet Lam98c46a12014-10-31 15:34:57 -070014222 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
14223 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14224
Wilson Yang6507c4e2013-10-01 20:11:19 -070014225 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14226 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014227 if (0 != status)
14228 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014229 return status;
14230 }
14231
14232 /*Retrieve halHandle*/
14233 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14234
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014235 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14236 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
14237 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014238 /* Delete the PMKID CSR cache */
14239 if (eHAL_STATUS_SUCCESS !=
14240 sme_RoamDelPMKIDfromCache(halHandle,
14241 pAdapter->sessionId, pmksa->bssid, FALSE)) {
14242 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
14243 MAC_ADDR_ARRAY(pmksa->bssid));
14244 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014245 }
14246
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014247 EXIT();
14248 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014249}
14250
Wilson Yang6507c4e2013-10-01 20:11:19 -070014251
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014252static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
14253 struct cfg80211_pmksa *pmksa)
14254{
14255 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014256
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014257 vos_ssr_protect(__func__);
14258 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
14259 vos_ssr_unprotect(__func__);
14260
14261 return ret;
14262
14263}
14264
14265static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014266{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014267 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14268 tHalHandle halHandle;
14269 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014270 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014271
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014272 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070014273
14274 /* Validate pAdapter */
14275 if (NULL == pAdapter)
14276 {
14277 hddLog(VOS_TRACE_LEVEL_ERROR,
14278 "%s: Invalid Adapter" ,__func__);
14279 return -EINVAL;
14280 }
14281
14282 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14283 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014284 if (0 != status)
14285 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014286 return status;
14287 }
14288
14289 /*Retrieve halHandle*/
14290 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14291
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014292 /* Flush the PMKID cache in CSR */
14293 if (eHAL_STATUS_SUCCESS !=
14294 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
14295 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
14296 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014297 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014298 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080014299 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014300}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014301
14302static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
14303{
14304 int ret;
14305
14306 vos_ssr_protect(__func__);
14307 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
14308 vos_ssr_unprotect(__func__);
14309
14310 return ret;
14311}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014312#endif
14313
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014314#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014315static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14316 struct net_device *dev,
14317 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014318{
14319 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14320 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014321 hdd_context_t *pHddCtx;
14322 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014323
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014324 ENTER();
14325
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014326 if (NULL == pAdapter)
14327 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014328 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014329 return -ENODEV;
14330 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014331 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14332 ret = wlan_hdd_validate_context(pHddCtx);
14333 if (0 != ret)
14334 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014335 return ret;
14336 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014337 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014338 if (NULL == pHddStaCtx)
14339 {
14340 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
14341 return -EINVAL;
14342 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014343
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014344 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14345 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
14346 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014347 // Added for debug on reception of Re-assoc Req.
14348 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
14349 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014350 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014351 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080014352 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014353 }
14354
14355#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080014356 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014357 ftie->ie_len);
14358#endif
14359
14360 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014361 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
14362 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014363 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014364
14365 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014366 return 0;
14367}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014368
14369static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14370 struct net_device *dev,
14371 struct cfg80211_update_ft_ies_params *ftie)
14372{
14373 int ret;
14374
14375 vos_ssr_protect(__func__);
14376 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
14377 vos_ssr_unprotect(__func__);
14378
14379 return ret;
14380}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014381#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014382
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014383#ifdef FEATURE_WLAN_SCAN_PNO
14384
14385void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
14386 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
14387{
14388 int ret;
14389 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
14390 hdd_context_t *pHddCtx;
14391
Nirav Shah80830bf2013-12-31 16:35:12 +053014392 ENTER();
14393
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014394 if (NULL == pAdapter)
14395 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014396 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014397 "%s: HDD adapter is Null", __func__);
14398 return ;
14399 }
14400
14401 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14402 if (NULL == pHddCtx)
14403 {
14404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14405 "%s: HDD context is Null!!!", __func__);
14406 return ;
14407 }
14408
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014409 spin_lock(&pHddCtx->schedScan_lock);
14410 if (TRUE == pHddCtx->isWiphySuspended)
14411 {
14412 pHddCtx->isSchedScanUpdatePending = TRUE;
14413 spin_unlock(&pHddCtx->schedScan_lock);
14414 hddLog(VOS_TRACE_LEVEL_INFO,
14415 "%s: Update cfg80211 scan database after it resume", __func__);
14416 return ;
14417 }
14418 spin_unlock(&pHddCtx->schedScan_lock);
14419
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014420 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
14421
14422 if (0 > ret)
14423 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
14424
14425 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014426 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14427 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014428}
14429
14430/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014431 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014432 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014433 */
14434static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
14435{
14436 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14437 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014438 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014439 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14440 int status = 0;
14441 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
14442
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014443 /* The current firmware design does not allow PNO during any
14444 * active sessions. Hence, determine the active sessions
14445 * and return a failure.
14446 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014447 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
14448 {
14449 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014450 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014451
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014452 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
14453 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
14454 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
14455 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
14456 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053014457 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014458 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014459 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014460 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014461 }
14462 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14463 pAdapterNode = pNext;
14464 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014465 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014466}
14467
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014468void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
14469{
14470 hdd_adapter_t *pAdapter = callbackContext;
14471 hdd_context_t *pHddCtx;
14472
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014473 ENTER();
14474
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014475 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
14476 {
14477 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14478 FL("Invalid adapter or adapter has invalid magic"));
14479 return;
14480 }
14481
14482 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14483 if (0 != wlan_hdd_validate_context(pHddCtx))
14484 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014485 return;
14486 }
14487
c_hpothub53c45d2014-08-18 16:53:14 +053014488 if (VOS_STATUS_SUCCESS != status)
14489 {
14490 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014491 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053014492 pHddCtx->isPnoEnable = FALSE;
14493 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014494
14495 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
14496 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014497 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014498}
14499
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014500/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014501 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
14502 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014503 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014504static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014505 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14506{
14507 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014508 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014509 hdd_context_t *pHddCtx;
14510 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014511 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053014512 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
14513 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014514 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
14515 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014516 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014517 hdd_config_t *pConfig = NULL;
14518 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014519
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014520 ENTER();
14521
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014522 if (NULL == pAdapter)
14523 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014524 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014525 "%s: HDD adapter is Null", __func__);
14526 return -ENODEV;
14527 }
14528
14529 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014530 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014531
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014532 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014533 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014534 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014535 }
14536
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014537 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014538 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14539 if (NULL == hHal)
14540 {
14541 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14542 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014543 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014544 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014545 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14546 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
14547 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053014548 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014549 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053014550 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014551 {
14552 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14553 "%s: aborting the existing scan is unsuccessfull", __func__);
14554 return -EBUSY;
14555 }
14556
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014557 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014558 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014559 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014560 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014561 return -EBUSY;
14562 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014563
c_hpothu37f21312014-04-09 21:49:54 +053014564 if (TRUE == pHddCtx->isPnoEnable)
14565 {
14566 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14567 FL("already PNO is enabled"));
14568 return -EBUSY;
14569 }
c_hpothu225aa7c2014-10-22 17:45:13 +053014570
14571 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
14572 {
14573 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14574 "%s: abort ROC failed ", __func__);
14575 return -EBUSY;
14576 }
14577
c_hpothu37f21312014-04-09 21:49:54 +053014578 pHddCtx->isPnoEnable = TRUE;
14579
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014580 pnoRequest.enable = 1; /*Enable PNO */
14581 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014582
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014583 if (( !pnoRequest.ucNetworksCount ) ||
14584 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014585 {
14586 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014587 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014588 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014589 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014590 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014591 goto error;
14592 }
14593
14594 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
14595 {
14596 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014597 "%s: Incorrect number of channels %d",
14598 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014599 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014600 goto error;
14601 }
14602
14603 /* Framework provides one set of channels(all)
14604 * common for all saved profile */
14605 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
14606 channels_allowed, &num_channels_allowed))
14607 {
14608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14609 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014610 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014611 goto error;
14612 }
14613 /* Checking each channel against allowed channel list */
14614 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053014615 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014616 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014617 char chList [(request->n_channels*5)+1];
14618 int len;
14619 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014620 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014621 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014622 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014623 if (request->channels[i]->hw_value == channels_allowed[indx])
14624 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014625 if ((!pConfig->enableDFSPnoChnlScan) &&
14626 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
14627 {
14628 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14629 "%s : Dropping DFS channel : %d",
14630 __func__,channels_allowed[indx]);
14631 num_ignore_dfs_ch++;
14632 break;
14633 }
14634
Nirav Shah80830bf2013-12-31 16:35:12 +053014635 valid_ch[num_ch++] = request->channels[i]->hw_value;
14636 len += snprintf(chList+len, 5, "%d ",
14637 request->channels[i]->hw_value);
14638 break ;
14639 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014640 }
14641 }
Nirav Shah80830bf2013-12-31 16:35:12 +053014642 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014643
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014644 /*If all channels are DFS and dropped, then ignore the PNO request*/
14645 if (num_ignore_dfs_ch == request->n_channels)
14646 {
14647 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14648 "%s : All requested channels are DFS channels", __func__);
14649 ret = -EINVAL;
14650 goto error;
14651 }
14652 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014653
14654 pnoRequest.aNetworks =
14655 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14656 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014657 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014658 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14659 FL("failed to allocate memory aNetworks %u"),
14660 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14661 goto error;
14662 }
14663 vos_mem_zero(pnoRequest.aNetworks,
14664 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14665
14666 /* Filling per profile params */
14667 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
14668 {
14669 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014670 request->match_sets[i].ssid.ssid_len;
14671
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014672 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
14673 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014674 {
14675 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014676 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014677 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014678 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014679 goto error;
14680 }
14681
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014682 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014683 request->match_sets[i].ssid.ssid,
14684 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14686 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014687 i, pnoRequest.aNetworks[i].ssId.ssId);
14688 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
14689 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
14690 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014691
14692 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014693 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
14694 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014695
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014696 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014697 }
14698
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014699 for (i = 0; i < request->n_ssids; i++)
14700 {
14701 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014702 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014703 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014704 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014705 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014706 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014707 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014708 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014709 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014710 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014711 break;
14712 }
14713 j++;
14714 }
14715 }
14716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14717 "Number of hidden networks being Configured = %d",
14718 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014719 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080014720 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014721
14722 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14723 if (pnoRequest.p24GProbeTemplate == NULL)
14724 {
14725 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14726 FL("failed to allocate memory p24GProbeTemplate %u"),
14727 SIR_PNO_MAX_PB_REQ_SIZE);
14728 goto error;
14729 }
14730
14731 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14732 if (pnoRequest.p5GProbeTemplate == NULL)
14733 {
14734 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14735 FL("failed to allocate memory p5GProbeTemplate %u"),
14736 SIR_PNO_MAX_PB_REQ_SIZE);
14737 goto error;
14738 }
14739
14740 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14741 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14742
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053014743 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
14744 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014745 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014746 pnoRequest.us24GProbeTemplateLen = request->ie_len;
14747 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
14748 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014749
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014750 pnoRequest.us5GProbeTemplateLen = request->ie_len;
14751 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
14752 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014753 }
14754
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014755 /* Driver gets only one time interval which is hardcoded in
14756 * supplicant for 10000ms. Taking power consumption into account 6 timers
14757 * will be used, Timervalue is increased exponentially i.e 10,20,40,
14758 * 80,160,320 secs. And number of scan cycle for each timer
14759 * is configurable through INI param gPNOScanTimerRepeatValue.
14760 * If it is set to 0 only one timer will be used and PNO scan cycle
14761 * will be repeated after each interval specified by supplicant
14762 * till PNO is disabled.
14763 */
14764 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014765 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014766 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014767 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014768 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
14769
14770 tempInterval = (request->interval)/1000;
14771 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14772 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
14773 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014774 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014775 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014776 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014777 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014778 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014779 tempInterval *= 2;
14780 }
14781 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014782 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014783
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014784 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014785
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014786 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014787 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
14788 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014789 pAdapter->pno_req_status = 0;
14790
Nirav Shah80830bf2013-12-31 16:35:12 +053014791 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14792 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014793 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
14794 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053014795
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014796 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014797 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014798 hdd_cfg80211_sched_scan_done_callback, pAdapter);
14799 if (eHAL_STATUS_SUCCESS != status)
14800 {
14801 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014802 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014803 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014804 goto error;
14805 }
14806
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014807 ret = wait_for_completion_timeout(
14808 &pAdapter->pno_comp_var,
14809 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
14810 if (0 >= ret)
14811 {
14812 // Did not receive the response for PNO enable in time.
14813 // Assuming the PNO enable was success.
14814 // Returning error from here, because we timeout, results
14815 // in side effect of Wifi (Wifi Setting) not to work.
14816 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14817 FL("Timed out waiting for PNO to be Enabled"));
14818 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014819 }
14820
14821 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053014822 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014823
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014824error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14826 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053014827 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014828 if (pnoRequest.aNetworks)
14829 vos_mem_free(pnoRequest.aNetworks);
14830 if (pnoRequest.p24GProbeTemplate)
14831 vos_mem_free(pnoRequest.p24GProbeTemplate);
14832 if (pnoRequest.p5GProbeTemplate)
14833 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014834
14835 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014836 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014837}
14838
14839/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014840 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
14841 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014842 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014843static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
14844 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14845{
14846 int ret;
14847
14848 vos_ssr_protect(__func__);
14849 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
14850 vos_ssr_unprotect(__func__);
14851
14852 return ret;
14853}
14854
14855/*
14856 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
14857 * Function to disable PNO
14858 */
14859static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014860 struct net_device *dev)
14861{
14862 eHalStatus status = eHAL_STATUS_FAILURE;
14863 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14864 hdd_context_t *pHddCtx;
14865 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014866 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014867 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014868
14869 ENTER();
14870
14871 if (NULL == pAdapter)
14872 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014873 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014874 "%s: HDD adapter is Null", __func__);
14875 return -ENODEV;
14876 }
14877
14878 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014879
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014880 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014881 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014882 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014883 "%s: HDD context is Null", __func__);
14884 return -ENODEV;
14885 }
14886
14887 /* The return 0 is intentional when isLogpInProgress and
14888 * isLoadUnloadInProgress. We did observe a crash due to a return of
14889 * failure in sched_scan_stop , especially for a case where the unload
14890 * of the happens at the same time. The function __cfg80211_stop_sched_scan
14891 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
14892 * success. If it returns a failure , then its next invocation due to the
14893 * clean up of the second interface will have the dev pointer corresponding
14894 * to the first one leading to a crash.
14895 */
14896 if (pHddCtx->isLogpInProgress)
14897 {
14898 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14899 "%s: LOGP in Progress. Ignore!!!", __func__);
14900 return ret;
14901 }
14902
Mihir Shete18156292014-03-11 15:38:30 +053014903 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014904 {
14905 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14906 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14907 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014908 }
14909
14910 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14911 if (NULL == hHal)
14912 {
14913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14914 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014915 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014916 }
14917
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014918 pnoRequest.enable = 0; /* Disable PNO */
14919 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014920
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014921 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14922 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
14923 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014924 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014925 pAdapter->sessionId,
14926 NULL, pAdapter);
14927 if (eHAL_STATUS_SUCCESS != status)
14928 {
14929 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14930 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014931 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014932 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014933 }
c_hpothu37f21312014-04-09 21:49:54 +053014934 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014935
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014936error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014937 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014938 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014939
14940 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014941 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014942}
14943
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014944/*
14945 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
14946 * NL interface to disable PNO
14947 */
14948static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
14949 struct net_device *dev)
14950{
14951 int ret;
14952
14953 vos_ssr_protect(__func__);
14954 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
14955 vos_ssr_unprotect(__func__);
14956
14957 return ret;
14958}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014959#endif /*FEATURE_WLAN_SCAN_PNO*/
14960
14961
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014962#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014963#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014964static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
14965 struct net_device *dev,
14966 u8 *peer, u8 action_code,
14967 u8 dialog_token,
14968 u16 status_code, u32 peer_capability,
14969 const u8 *buf, size_t len)
14970#else /* TDLS_MGMT_VERSION2 */
14971#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
14972static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
14973 struct net_device *dev,
14974 const u8 *peer, u8 action_code,
14975 u8 dialog_token, u16 status_code,
14976 u32 peer_capability, bool initiator,
14977 const u8 *buf, size_t len)
14978#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
14979static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
14980 struct net_device *dev,
14981 const u8 *peer, u8 action_code,
14982 u8 dialog_token, u16 status_code,
14983 u32 peer_capability, const u8 *buf,
14984 size_t len)
14985#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
14986static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
14987 struct net_device *dev,
14988 u8 *peer, u8 action_code,
14989 u8 dialog_token,
14990 u16 status_code, u32 peer_capability,
14991 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014992#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014993static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
14994 struct net_device *dev,
14995 u8 *peer, u8 action_code,
14996 u8 dialog_token,
14997 u16 status_code, const u8 *buf,
14998 size_t len)
14999#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015000#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015001{
15002
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015003 hdd_adapter_t *pAdapter;
15004 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015005 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070015006 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080015007 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070015008 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015009 int ret;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015010#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015011 u32 peer_capability = 0;
15012#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015013 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015014
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015015 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15016 if (NULL == pAdapter)
15017 {
15018 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15019 "%s: Adapter is NULL",__func__);
15020 return -EINVAL;
15021 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015022 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15023 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
15024 pAdapter->sessionId, action_code));
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015025 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015026 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015027 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015028 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015029 "Invalid arguments");
15030 return -EINVAL;
15031 }
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015032 if (pHddCtx->isLogpInProgress)
15033 {
15034 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15035 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053015036 wlan_hdd_tdls_set_link_status(pAdapter,
15037 peer,
15038 eTDLS_LINK_IDLE,
15039 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015040 return -EBUSY;
15041 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015042 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
15043 {
15044 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15045 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15046 return -EAGAIN;
15047 }
Hoonki Lee27511902013-03-14 18:19:06 -070015048 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015049 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015050 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015051 "%s: TDLS mode is disabled OR not enabled in FW."
15052 MAC_ADDRESS_STR " action %d declined.",
15053 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015054 return -ENOTSUPP;
15055 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015056
Hoonki Lee27511902013-03-14 18:19:06 -070015057 /* other than teardown frame, other mgmt frames are not sent if disabled */
15058 if (SIR_MAC_TDLS_TEARDOWN != action_code)
15059 {
15060 /* if tdls_mode is disabled to respond to peer's request */
15061 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
15062 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015063 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015064 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015065 " TDLS mode is disabled. action %d declined.",
15066 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070015067
15068 return -ENOTSUPP;
15069 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053015070
15071 if (vos_max_concurrent_connections_reached())
15072 {
15073 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15074 return -EINVAL;
15075 }
Hoonki Lee27511902013-03-14 18:19:06 -070015076 }
15077
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015078 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
15079 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053015080 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015081 {
15082 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015083 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015084 " TDLS setup is ongoing. action %d declined.",
15085 __func__, MAC_ADDR_ARRAY(peer), action_code);
15086 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015087 }
15088 }
15089
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015090 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
15091 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080015092 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015093 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15094 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015095 {
15096 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
15097 we return error code at 'add_station()'. Hence we have this
15098 check again in addtion to add_station().
15099 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015100 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015101 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015102 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15103 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015104 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
15105 __func__, MAC_ADDR_ARRAY(peer), action_code,
15106 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053015107 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080015108 }
15109 else
15110 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015111 /* maximum reached. tweak to send error code to peer and return
15112 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015113 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15115 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015116 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
15117 __func__, MAC_ADDR_ARRAY(peer), status_code,
15118 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070015119 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015120 /* fall through to send setup resp with failure status
15121 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015122 }
15123 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015124 else
15125 {
15126 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053015127 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015128 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015129 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015130 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015131 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
15132 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015133 return -EPERM;
15134 }
15135 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015136 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015137
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015138 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015139 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015140 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
15141 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015142
Hoonki Leea34dd892013-02-05 22:56:02 -080015143 /*Except teardown responder will not be used so just make 0*/
15144 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015145 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080015146 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015147
15148 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015149 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015150
15151 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
15152 responder = pTdlsPeer->is_responder;
15153 else
Hoonki Leea34dd892013-02-05 22:56:02 -080015154 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015156 "%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 -070015157 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
15158 dialog_token, status_code, len);
15159 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080015160 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015161 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015162
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015163 /* For explicit trigger of DIS_REQ come out of BMPS for
15164 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070015165 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015166 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
15167 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070015168 {
15169 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
15170 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015171 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015172 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015173 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
15174 if (status != VOS_STATUS_SUCCESS) {
15175 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
15176 }
Hoonki Lee14621352013-04-16 17:51:19 -070015177 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015178 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015179 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015180 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
15181 }
15182 }
Hoonki Lee14621352013-04-16 17:51:19 -070015183 }
15184
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015185 /* make sure doesn't call send_mgmt() while it is pending */
15186 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
15187 {
15188 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015189 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015190 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015191 ret = -EBUSY;
15192 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015193 }
15194
15195 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015196 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
15197
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015198 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015199 peer, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015200
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015201 if (VOS_STATUS_SUCCESS != status)
15202 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015203 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15204 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015205 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015206 ret = -EINVAL;
15207 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015208 }
15209
Hoonki Leed37cbb32013-04-20 00:31:14 -070015210 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
15211 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
15212
15213 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015214 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070015215 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015216 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070015217 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015218 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080015219
15220 if (pHddCtx->isLogpInProgress)
15221 {
15222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15223 "%s: LOGP in Progress. Ignore!!!", __func__);
15224 return -EAGAIN;
15225 }
15226
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015227 ret = -EINVAL;
15228 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015229 }
15230
Gopichand Nakkala05922802013-03-14 12:23:19 -070015231 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070015232 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015233 ret = max_sta_failed;
15234 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070015235 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015236
Hoonki Leea34dd892013-02-05 22:56:02 -080015237 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
15238 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015239 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015240 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15241 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015242 }
15243 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
15244 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015245 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015246 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15247 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015248 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015249
15250 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015251
15252tx_failed:
15253 /* add_station will be called before sending TDLS_SETUP_REQ and
15254 * TDLS_SETUP_RSP and as part of add_station driver will enable
15255 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
15256 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
15257 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
15258 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
15259 */
15260
15261 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
15262 (SIR_MAC_TDLS_SETUP_RSP == action_code))
15263 wlan_hdd_tdls_check_bmps(pAdapter);
15264 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015265}
15266
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015267#if TDLS_MGMT_VERSION2
15268static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15269 u8 *peer, u8 action_code, u8 dialog_token,
15270 u16 status_code, u32 peer_capability,
15271 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015272#else /* TDLS_MGMT_VERSION2 */
15273#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
15274static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15275 struct net_device *dev,
15276 const u8 *peer, u8 action_code,
15277 u8 dialog_token, u16 status_code,
15278 u32 peer_capability, bool initiator,
15279 const u8 *buf, size_t len)
15280#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15281static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15282 struct net_device *dev,
15283 const u8 *peer, u8 action_code,
15284 u8 dialog_token, u16 status_code,
15285 u32 peer_capability, const u8 *buf,
15286 size_t len)
15287#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
15288static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15289 struct net_device *dev,
15290 u8 *peer, u8 action_code,
15291 u8 dialog_token,
15292 u16 status_code, u32 peer_capability,
15293 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015294#else
15295static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15296 u8 *peer, u8 action_code, u8 dialog_token,
15297 u16 status_code, const u8 *buf, size_t len)
15298#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015299#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015300{
15301 int ret;
15302
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015303 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015304#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015305 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15306 dialog_token, status_code,
15307 peer_capability, buf, len);
15308#else /* TDLS_MGMT_VERSION2 */
15309#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
15310 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15311 dialog_token, status_code,
15312 peer_capability, initiator,
15313 buf, len);
15314#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
15315 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15316 dialog_token, status_code,
15317 peer_capability, buf, len);
15318#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
15319 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15320 dialog_token, status_code,
15321 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015322#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015323 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15324 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015325#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015326#endif
15327 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015328
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015329 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015330}
Atul Mittal115287b2014-07-08 13:26:33 +053015331
15332int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015333#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15334 const u8 *peer,
15335#else
Atul Mittal115287b2014-07-08 13:26:33 +053015336 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015337#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015338 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053015339 cfg80211_exttdls_callback callback)
15340{
15341
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015342 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053015343 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015344 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053015345 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15346 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
15347 __func__, MAC_ADDR_ARRAY(peer));
15348
15349 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
15350 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
15351
15352 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015353 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
15354 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
15355 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053015356 return -ENOTSUPP;
15357 }
15358
15359 /* To cater the requirement of establishing the TDLS link
15360 * irrespective of the data traffic , get an entry of TDLS peer.
15361 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015362 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015363 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
15364 if (pTdlsPeer == NULL) {
15365 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15366 "%s: peer " MAC_ADDRESS_STR " not existing",
15367 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015368 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015369 return -EINVAL;
15370 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015371 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015372
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053015373 /* check FW TDLS Off Channel capability */
15374 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053015375 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053015376 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015377 {
15378 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
15379 pTdlsPeer->peerParams.global_operating_class =
15380 tdls_peer_params->global_operating_class;
15381 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
15382 pTdlsPeer->peerParams.min_bandwidth_kbps =
15383 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015384 /* check configured channel is valid, non dfs and
15385 * not current operating channel */
15386 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
15387 tdls_peer_params->channel)) &&
15388 (pHddStaCtx) &&
15389 (tdls_peer_params->channel !=
15390 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015391 {
15392 pTdlsPeer->isOffChannelConfigured = TRUE;
15393 }
15394 else
15395 {
15396 pTdlsPeer->isOffChannelConfigured = FALSE;
15397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15398 "%s: Configured Tdls Off Channel is not valid", __func__);
15399
15400 }
15401 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015402 "%s: tdls_off_channel %d isOffChannelConfigured %d "
15403 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015404 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015405 pTdlsPeer->isOffChannelConfigured,
15406 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015407 }
15408 else
15409 {
15410 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053015411 "%s: TDLS off channel FW capability %d, "
15412 "host capab %d or Invalid TDLS Peer Params", __func__,
15413 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
15414 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015415 }
15416
Atul Mittal115287b2014-07-08 13:26:33 +053015417 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
15418
15419 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15420 " %s TDLS Add Force Peer Failed",
15421 __func__);
15422 return -EINVAL;
15423 }
15424 /*EXT TDLS*/
15425
15426 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
15427 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15428 " %s TDLS set callback Failed",
15429 __func__);
15430 return -EINVAL;
15431 }
15432
15433 return(0);
15434
15435}
15436
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015437int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
15438#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15439 const u8 *peer
15440#else
15441 u8 *peer
15442#endif
15443)
Atul Mittal115287b2014-07-08 13:26:33 +053015444{
15445
15446 hddTdlsPeer_t *pTdlsPeer;
15447 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15448 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15449 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
15450 __func__, MAC_ADDR_ARRAY(peer));
15451
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015452 if (0 != wlan_hdd_validate_context(pHddCtx)) {
15453 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
15454 return -EINVAL;
15455 }
15456
Atul Mittal115287b2014-07-08 13:26:33 +053015457 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
15458 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
15459
15460 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015461 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
15462 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
15463 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053015464 return -ENOTSUPP;
15465 }
15466
15467
15468 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15469
15470 if ( NULL == pTdlsPeer ) {
15471 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015472 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053015473 __func__, MAC_ADDR_ARRAY(peer));
15474 return -EINVAL;
15475 }
15476 else {
15477 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
15478 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015479 /* if channel switch is configured, reset
15480 the channel for this peer */
15481 if (TRUE == pTdlsPeer->isOffChannelConfigured)
15482 {
15483 pTdlsPeer->peerParams.channel = 0;
15484 pTdlsPeer->isOffChannelConfigured = FALSE;
15485 }
Atul Mittal115287b2014-07-08 13:26:33 +053015486 }
15487
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015488 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
15489 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053015490 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015491 }
Atul Mittal115287b2014-07-08 13:26:33 +053015492
15493 /*EXT TDLS*/
15494
15495 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
15496
15497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15498 " %s TDLS set callback Failed",
15499 __func__);
15500 return -EINVAL;
15501 }
15502 return(0);
15503
15504}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015505static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015506#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15507 const u8 *peer,
15508#else
15509 u8 *peer,
15510#endif
15511 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015512{
15513 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15514 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015515 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015516 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015517
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015518 ENTER();
15519
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015520 if (!pAdapter) {
15521 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
15522 return -EINVAL;
15523 }
15524
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015525 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15526 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
15527 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015528 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015529 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015530 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070015531 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015532 return -EINVAL;
15533 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015534
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015535 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015536 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015537 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015538 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015539 }
15540
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015541
15542 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015543 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015544 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015545 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015546 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
15547 "Cannot process TDLS commands",
15548 pHddCtx->cfg_ini->fEnableTDLSSupport,
15549 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015550 return -ENOTSUPP;
15551 }
15552
15553 switch (oper) {
15554 case NL80211_TDLS_ENABLE_LINK:
15555 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015556 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015557 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015558 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053015559 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015560 tANI_U16 numCurrTdlsPeers = 0;
15561 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015562 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015563
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15565 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
15566 __func__, MAC_ADDR_ARRAY(peer));
Sunil Dutt41de4e22013-11-14 18:09:02 +053015567 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053015568 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053015569 if ( NULL == pTdlsPeer ) {
15570 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15571 " (oper %d) not exsting. ignored",
15572 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15573 return -EINVAL;
15574 }
15575
15576 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15577 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15578 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15579 "NL80211_TDLS_ENABLE_LINK");
15580
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070015581 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
15582 {
15583 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
15584 MAC_ADDRESS_STR " failed",
15585 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
15586 return -EINVAL;
15587 }
15588
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053015589 /* before starting tdls connection, set tdls
15590 * off channel established status to default value */
15591 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015592 /* TDLS Off Channel, Disable tdls channel switch,
15593 when there are more than one tdls link */
15594 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053015595 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015596 {
15597 /* get connected peer and send disable tdls off chan */
15598 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015599 if ((connPeer) &&
15600 (connPeer->isOffChannelSupported == TRUE) &&
15601 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015602 {
15603 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15604 "%s: More then one peer connected, Disable "
15605 "TDLS channel switch", __func__);
15606
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015607 connPeer->isOffChannelEstablished = FALSE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015608 ret = sme_SendTdlsChanSwitchReq(
15609 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015610 pAdapter->sessionId,
15611 connPeer->peerMac,
15612 connPeer->peerParams.channel,
15613 TDLS_OFF_CHANNEL_BW_OFFSET,
15614 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015615 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015616 hddLog(VOS_TRACE_LEVEL_ERROR,
15617 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015618 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015619 }
15620 else
15621 {
15622 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15623 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015624 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015625 "isOffChannelConfigured %d",
15626 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015627 (connPeer ? (connPeer->isOffChannelSupported)
15628 : -1),
15629 (connPeer ? (connPeer->isOffChannelConfigured)
15630 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015631 }
15632 }
15633
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015634 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015635 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015636 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053015637
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015638 if (0 != wlan_hdd_tdls_get_link_establish_params(
15639 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015640 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015641 return -EINVAL;
15642 }
15643 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015644
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015645 ret = sme_SendTdlsLinkEstablishParams(
15646 WLAN_HDD_GET_HAL_CTX(pAdapter),
15647 pAdapter->sessionId, peer,
15648 &tdlsLinkEstablishParams);
15649 if (ret != VOS_STATUS_SUCCESS) {
15650 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
15651 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015652 /* Send TDLS peer UAPSD capabilities to the firmware and
15653 * register with the TL on after the response for this operation
15654 * is received .
15655 */
15656 ret = wait_for_completion_interruptible_timeout(
15657 &pAdapter->tdls_link_establish_req_comp,
15658 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
15659 if (ret <= 0)
15660 {
15661 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015662 FL("Link Establish Request Failed Status %ld"),
15663 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015664 return -EINVAL;
15665 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015666 }
Atul Mittal115287b2014-07-08 13:26:33 +053015667 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15668 eTDLS_LINK_CONNECTED,
15669 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053015670 staDesc.ucSTAId = pTdlsPeer->staId;
15671 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015672 ret = WLANTL_UpdateTdlsSTAClient(
15673 pHddCtx->pvosContext,
15674 &staDesc);
15675 if (ret != VOS_STATUS_SUCCESS) {
15676 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
15677 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053015678
Gopichand Nakkala471708b2013-06-04 20:03:01 +053015679 /* Mark TDLS client Authenticated .*/
15680 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
15681 pTdlsPeer->staId,
15682 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015683 if (VOS_STATUS_SUCCESS == status)
15684 {
Hoonki Lee14621352013-04-16 17:51:19 -070015685 if (pTdlsPeer->is_responder == 0)
15686 {
15687 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
15688
15689 wlan_hdd_tdls_timer_restart(pAdapter,
15690 &pTdlsPeer->initiatorWaitTimeoutTimer,
15691 WAIT_TIME_TDLS_INITIATOR);
15692 /* suspend initiator TX until it receives direct packet from the
15693 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015694 ret = WLANTL_SuspendDataTx(
15695 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15696 &staId, NULL);
15697 if (ret != VOS_STATUS_SUCCESS) {
15698 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
15699 }
Hoonki Lee14621352013-04-16 17:51:19 -070015700 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015701
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015702 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015703 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015704 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015705 suppChannelLen =
15706 tdlsLinkEstablishParams.supportedChannelsLen;
15707
15708 if ((suppChannelLen > 0) &&
15709 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
15710 {
15711 tANI_U8 suppPeerChannel = 0;
15712 int i = 0;
15713 for (i = 0U; i < suppChannelLen; i++)
15714 {
15715 suppPeerChannel =
15716 tdlsLinkEstablishParams.supportedChannels[i];
15717
15718 pTdlsPeer->isOffChannelSupported = FALSE;
15719 if (suppPeerChannel ==
15720 pTdlsPeer->peerParams.channel)
15721 {
15722 pTdlsPeer->isOffChannelSupported = TRUE;
15723 break;
15724 }
15725 }
15726 }
15727 else
15728 {
15729 pTdlsPeer->isOffChannelSupported = FALSE;
15730 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015731 }
15732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15733 "%s: TDLS channel switch request for channel "
15734 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015735 "%d isOffChannelSupported %d", __func__,
15736 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015737 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015738 suppChannelLen,
15739 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015740
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015741 /* TDLS Off Channel, Enable tdls channel switch,
15742 when their is only one tdls link and it supports */
15743 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15744 if ((numCurrTdlsPeers == 1) &&
15745 (TRUE == pTdlsPeer->isOffChannelSupported) &&
15746 (TRUE == pTdlsPeer->isOffChannelConfigured))
15747 {
15748 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15749 "%s: Send TDLS channel switch request for channel %d",
15750 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015751
15752 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015753 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
15754 pAdapter->sessionId,
15755 pTdlsPeer->peerMac,
15756 pTdlsPeer->peerParams.channel,
15757 TDLS_OFF_CHANNEL_BW_OFFSET,
15758 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015759 if (ret != VOS_STATUS_SUCCESS) {
15760 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
15761 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015762 }
15763 else
15764 {
15765 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15766 "%s: TDLS channel switch request not sent"
15767 " numCurrTdlsPeers %d "
15768 "isOffChannelSupported %d "
15769 "isOffChannelConfigured %d",
15770 __func__, numCurrTdlsPeers,
15771 pTdlsPeer->isOffChannelSupported,
15772 pTdlsPeer->isOffChannelConfigured);
15773 }
15774
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015775 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015776 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015777
15778 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015779 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
15780 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015781 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015782 int ac;
15783 uint8 ucAc[4] = { WLANTL_AC_VO,
15784 WLANTL_AC_VI,
15785 WLANTL_AC_BK,
15786 WLANTL_AC_BE };
15787 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
15788 for(ac=0; ac < 4; ac++)
15789 {
15790 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15791 pTdlsPeer->staId, ucAc[ac],
15792 tlTid[ac], tlTid[ac], 0, 0,
15793 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015794 if (status != VOS_STATUS_SUCCESS) {
15795 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
15796 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015797 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015798 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015799 }
15800
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015801 }
15802 break;
15803 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080015804 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015805 tANI_U16 numCurrTdlsPeers = 0;
15806 hddTdlsPeer_t *connPeer = NULL;
15807
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015808 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15809 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
15810 __func__, MAC_ADDR_ARRAY(peer));
15811
Sunil Dutt41de4e22013-11-14 18:09:02 +053015812 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15813
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015814
Sunil Dutt41de4e22013-11-14 18:09:02 +053015815 if ( NULL == pTdlsPeer ) {
15816 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15817 " (oper %d) not exsting. ignored",
15818 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15819 return -EINVAL;
15820 }
15821
15822 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15823 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15824 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15825 "NL80211_TDLS_DISABLE_LINK");
15826
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015827 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080015828 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015829 long status;
15830
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053015831 /* set tdls off channel status to false for this peer */
15832 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053015833 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15834 eTDLS_LINK_TEARING,
15835 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
15836 eTDLS_LINK_UNSPECIFIED:
15837 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015838 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
15839
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015840 status = sme_DeleteTdlsPeerSta(
15841 WLAN_HDD_GET_HAL_CTX(pAdapter),
15842 pAdapter->sessionId, peer );
15843 if (status != VOS_STATUS_SUCCESS) {
15844 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
15845 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015846
15847 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
15848 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053015849 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053015850 eTDLS_LINK_IDLE,
15851 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015852 if (status <= 0)
15853 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015854 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15855 "%s: Del station failed status %ld",
15856 __func__, status);
15857 return -EPERM;
15858 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015859
15860 /* TDLS Off Channel, Enable tdls channel switch,
15861 when their is only one tdls link and it supports */
15862 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15863 if (numCurrTdlsPeers == 1)
15864 {
15865 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
15866 if ((connPeer) &&
15867 (connPeer->isOffChannelSupported == TRUE) &&
15868 (connPeer->isOffChannelConfigured == TRUE))
15869 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015870 connPeer->isOffChannelEstablished = TRUE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015871 status = sme_SendTdlsChanSwitchReq(
15872 WLAN_HDD_GET_HAL_CTX(pAdapter),
15873 pAdapter->sessionId,
15874 connPeer->peerMac,
15875 connPeer->peerParams.channel,
15876 TDLS_OFF_CHANNEL_BW_OFFSET,
15877 TDLS_CHANNEL_SWITCH_ENABLE);
15878 if (status != VOS_STATUS_SUCCESS) {
15879 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
15880 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015881 }
15882 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15883 "%s: TDLS channel switch "
15884 "isOffChannelSupported %d "
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015885 "isOffChannelConfigured %d "
15886 "isOffChannelEstablished %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015887 __func__,
15888 (connPeer ? connPeer->isOffChannelSupported : -1),
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015889 (connPeer ? connPeer->isOffChannelConfigured : -1),
15890 (connPeer ? connPeer->isOffChannelEstablished : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015891 }
15892 else
15893 {
15894 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15895 "%s: TDLS channel switch request not sent "
15896 "numCurrTdlsPeers %d ",
15897 __func__, numCurrTdlsPeers);
15898 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015899 }
15900 else
15901 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015902 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15903 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080015904 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015905 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015906 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015907 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015908 {
Atul Mittal115287b2014-07-08 13:26:33 +053015909 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015910
Atul Mittal115287b2014-07-08 13:26:33 +053015911 if (0 != status)
15912 {
15913 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015914 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053015915 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015916 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053015917 break;
15918 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015919 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015920 {
Atul Mittal115287b2014-07-08 13:26:33 +053015921 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
15922 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015923 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053015924 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015925
Atul Mittal115287b2014-07-08 13:26:33 +053015926 if (0 != status)
15927 {
15928 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015929 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053015930 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053015931 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053015932 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015933 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015934 case NL80211_TDLS_DISCOVERY_REQ:
15935 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015936 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015937 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015938 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015939 return -ENOTSUPP;
15940 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15942 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015943 return -ENOTSUPP;
15944 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015945
15946 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015947 return 0;
15948}
Chilam NG571c65a2013-01-19 12:27:36 +053015949
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015950static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015951#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15952 const u8 *peer,
15953#else
15954 u8 *peer,
15955#endif
15956 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015957{
15958 int ret;
15959
15960 vos_ssr_protect(__func__);
15961 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
15962 vos_ssr_unprotect(__func__);
15963
15964 return ret;
15965}
15966
Chilam NG571c65a2013-01-19 12:27:36 +053015967int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
15968 struct net_device *dev, u8 *peer)
15969{
Arif Hussaina7c8e412013-11-20 11:06:42 -080015970 hddLog(VOS_TRACE_LEVEL_INFO,
15971 "tdls send discover req: "MAC_ADDRESS_STR,
15972 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053015973
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015974#if TDLS_MGMT_VERSION2
15975 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15976 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
15977#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015978#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
15979 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15980 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
15981#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15982 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15983 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
15984#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
15985 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15986 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
15987#else
Chilam NG571c65a2013-01-19 12:27:36 +053015988 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15989 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015990#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015991#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053015992}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015993#endif
15994
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015995#ifdef WLAN_FEATURE_GTK_OFFLOAD
15996/*
15997 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
15998 * Callback rountine called upon receiving response for
15999 * get offload info
16000 */
16001void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
16002 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
16003{
16004
16005 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016006 tANI_U8 tempReplayCounter[8];
16007 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016008
16009 ENTER();
16010
16011 if (NULL == pAdapter)
16012 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016013 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016014 "%s: HDD adapter is Null", __func__);
16015 return ;
16016 }
16017
16018 if (NULL == pGtkOffloadGetInfoRsp)
16019 {
16020 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16021 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
16022 return ;
16023 }
16024
16025 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
16026 {
16027 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16028 "%s: wlan Failed to get replay counter value",
16029 __func__);
16030 return ;
16031 }
16032
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016033 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16034 /* Update replay counter */
16035 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
16036 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16037
16038 {
16039 /* changing from little to big endian since supplicant
16040 * works on big endian format
16041 */
16042 int i;
16043 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16044
16045 for (i = 0; i < 8; i++)
16046 {
16047 tempReplayCounter[7-i] = (tANI_U8)p[i];
16048 }
16049 }
16050
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016051 /* Update replay counter to NL */
16052 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016053 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016054}
16055
16056/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016057 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016058 * This function is used to offload GTK rekeying job to the firmware.
16059 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016060int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016061 struct cfg80211_gtk_rekey_data *data)
16062{
16063 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16064 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16065 hdd_station_ctx_t *pHddStaCtx;
16066 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016067 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016068 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016069 eHalStatus status = eHAL_STATUS_FAILURE;
16070
16071 ENTER();
16072
16073 if (NULL == pAdapter)
16074 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016075 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016076 "%s: HDD adapter is Null", __func__);
16077 return -ENODEV;
16078 }
16079
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016080 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16081 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
16082 pAdapter->sessionId, pAdapter->device_mode));
16083
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016084 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016085 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016086 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016087 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016088 }
16089
16090 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16091 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16092 if (NULL == hHal)
16093 {
16094 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16095 "%s: HAL context is Null!!!", __func__);
16096 return -EAGAIN;
16097 }
16098
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016099 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
16100 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
16101 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
16102 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016103 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016104 {
16105 /* changing from big to little endian since driver
16106 * works on little endian format
16107 */
16108 tANI_U8 *p =
16109 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
16110 int i;
16111
16112 for (i = 0; i < 8; i++)
16113 {
16114 p[7-i] = data->replay_ctr[i];
16115 }
16116 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016117
16118 if (TRUE == pHddCtx->hdd_wlan_suspended)
16119 {
16120 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016121 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
16122 sizeof (tSirGtkOffloadParams));
16123 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016124 pAdapter->sessionId);
16125
16126 if (eHAL_STATUS_SUCCESS != status)
16127 {
16128 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16129 "%s: sme_SetGTKOffload failed, returned %d",
16130 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016131
16132 /* Need to clear any trace of key value in the memory.
16133 * Thus zero out the memory even though it is local
16134 * variable.
16135 */
16136 vos_mem_zero(&hddGtkOffloadReqParams,
16137 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016138 return status;
16139 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016140 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16141 "%s: sme_SetGTKOffload successfull", __func__);
16142 }
16143 else
16144 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016145 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16146 "%s: wlan not suspended GTKOffload request is stored",
16147 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016148 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016149
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016150 /* Need to clear any trace of key value in the memory.
16151 * Thus zero out the memory even though it is local
16152 * variable.
16153 */
16154 vos_mem_zero(&hddGtkOffloadReqParams,
16155 sizeof(hddGtkOffloadReqParams));
16156
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016157 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016158 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016159}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016160
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016161int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
16162 struct cfg80211_gtk_rekey_data *data)
16163{
16164 int ret;
16165
16166 vos_ssr_protect(__func__);
16167 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
16168 vos_ssr_unprotect(__func__);
16169
16170 return ret;
16171}
16172#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016173/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016174 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016175 * This function is used to set access control policy
16176 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016177static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
16178 struct net_device *dev,
16179 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016180{
16181 int i;
16182 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16183 hdd_hostapd_state_t *pHostapdState;
16184 tsap_Config_t *pConfig;
16185 v_CONTEXT_t pVosContext = NULL;
16186 hdd_context_t *pHddCtx;
16187 int status;
16188
16189 ENTER();
16190
16191 if (NULL == pAdapter)
16192 {
16193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16194 "%s: HDD adapter is Null", __func__);
16195 return -ENODEV;
16196 }
16197
16198 if (NULL == params)
16199 {
16200 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16201 "%s: params is Null", __func__);
16202 return -EINVAL;
16203 }
16204
16205 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16206 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016207 if (0 != status)
16208 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016209 return status;
16210 }
16211
16212 pVosContext = pHddCtx->pvosContext;
16213 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
16214
16215 if (NULL == pHostapdState)
16216 {
16217 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16218 "%s: pHostapdState is Null", __func__);
16219 return -EINVAL;
16220 }
16221
16222 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
16223 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016224 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16225 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
16226 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016227
16228 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
16229 {
16230 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
16231
16232 /* default value */
16233 pConfig->num_accept_mac = 0;
16234 pConfig->num_deny_mac = 0;
16235
16236 /**
16237 * access control policy
16238 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
16239 * listed in hostapd.deny file.
16240 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
16241 * listed in hostapd.accept file.
16242 */
16243 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
16244 {
16245 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
16246 }
16247 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
16248 {
16249 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
16250 }
16251 else
16252 {
16253 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16254 "%s:Acl Policy : %d is not supported",
16255 __func__, params->acl_policy);
16256 return -ENOTSUPP;
16257 }
16258
16259 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
16260 {
16261 pConfig->num_accept_mac = params->n_acl_entries;
16262 for (i = 0; i < params->n_acl_entries; i++)
16263 {
16264 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16265 "** Add ACL MAC entry %i in WhiletList :"
16266 MAC_ADDRESS_STR, i,
16267 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
16268
16269 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
16270 sizeof(qcmacaddr));
16271 }
16272 }
16273 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
16274 {
16275 pConfig->num_deny_mac = params->n_acl_entries;
16276 for (i = 0; i < params->n_acl_entries; i++)
16277 {
16278 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16279 "** Add ACL MAC entry %i in BlackList :"
16280 MAC_ADDRESS_STR, i,
16281 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
16282
16283 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
16284 sizeof(qcmacaddr));
16285 }
16286 }
16287
16288 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
16289 {
16290 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16291 "%s: SAP Set Mac Acl fail", __func__);
16292 return -EINVAL;
16293 }
16294 }
16295 else
16296 {
16297 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016298 "%s: Invalid device_mode = %s (%d)",
16299 __func__, hdd_device_modetoString(pAdapter->device_mode),
16300 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016301 return -EINVAL;
16302 }
16303
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016304 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016305 return 0;
16306}
16307
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016308static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
16309 struct net_device *dev,
16310 const struct cfg80211_acl_data *params)
16311{
16312 int ret;
16313 vos_ssr_protect(__func__);
16314 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
16315 vos_ssr_unprotect(__func__);
16316
16317 return ret;
16318}
16319
Leo Chang9056f462013-08-01 19:21:11 -070016320#ifdef WLAN_NL80211_TESTMODE
16321#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070016322void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070016323(
16324 void *pAdapter,
16325 void *indCont
16326)
16327{
Leo Changd9df8aa2013-09-26 13:32:26 -070016328 tSirLPHBInd *lphbInd;
16329 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053016330 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070016331
16332 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016333 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070016334
c_hpothu73f35e62014-04-18 13:40:08 +053016335 if (pAdapter == NULL)
16336 {
16337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16338 "%s: pAdapter is NULL\n",__func__);
16339 return;
16340 }
16341
Leo Chang9056f462013-08-01 19:21:11 -070016342 if (NULL == indCont)
16343 {
16344 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016345 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070016346 return;
16347 }
16348
c_hpothu73f35e62014-04-18 13:40:08 +053016349 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070016350 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070016351 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053016352 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070016353 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070016354 GFP_ATOMIC);
16355 if (!skb)
16356 {
16357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16358 "LPHB timeout, NL buffer alloc fail");
16359 return;
16360 }
16361
Leo Changac3ba772013-10-07 09:47:04 -070016362 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070016363 {
16364 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16365 "WLAN_HDD_TM_ATTR_CMD put fail");
16366 goto nla_put_failure;
16367 }
Leo Changac3ba772013-10-07 09:47:04 -070016368 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070016369 {
16370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16371 "WLAN_HDD_TM_ATTR_TYPE put fail");
16372 goto nla_put_failure;
16373 }
Leo Changac3ba772013-10-07 09:47:04 -070016374 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070016375 sizeof(tSirLPHBInd), lphbInd))
16376 {
16377 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16378 "WLAN_HDD_TM_ATTR_DATA put fail");
16379 goto nla_put_failure;
16380 }
Leo Chang9056f462013-08-01 19:21:11 -070016381 cfg80211_testmode_event(skb, GFP_ATOMIC);
16382 return;
16383
16384nla_put_failure:
16385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16386 "NLA Put fail");
16387 kfree_skb(skb);
16388
16389 return;
16390}
16391#endif /* FEATURE_WLAN_LPHB */
16392
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016393static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070016394{
16395 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
16396 int err = 0;
16397#ifdef FEATURE_WLAN_LPHB
16398 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070016399 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016400
16401 ENTER();
16402
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016403 err = wlan_hdd_validate_context(pHddCtx);
16404 if (0 != err)
16405 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016406 return err;
16407 }
Leo Chang9056f462013-08-01 19:21:11 -070016408#endif /* FEATURE_WLAN_LPHB */
16409
16410 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
16411 if (err)
16412 {
16413 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16414 "%s Testmode INV ATTR", __func__);
16415 return err;
16416 }
16417
16418 if (!tb[WLAN_HDD_TM_ATTR_CMD])
16419 {
16420 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16421 "%s Testmode INV CMD", __func__);
16422 return -EINVAL;
16423 }
16424
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016425 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16426 TRACE_CODE_HDD_CFG80211_TESTMODE,
16427 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070016428 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
16429 {
16430#ifdef FEATURE_WLAN_LPHB
16431 /* Low Power Heartbeat configuration request */
16432 case WLAN_HDD_TM_CMD_WLAN_HB:
16433 {
16434 int buf_len;
16435 void *buf;
16436 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080016437 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070016438
16439 if (!tb[WLAN_HDD_TM_ATTR_DATA])
16440 {
16441 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16442 "%s Testmode INV DATA", __func__);
16443 return -EINVAL;
16444 }
16445
16446 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
16447 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080016448
16449 hb_params_temp =(tSirLPHBReq *)buf;
16450 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
16451 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
16452 return -EINVAL;
16453
Leo Chang9056f462013-08-01 19:21:11 -070016454 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
16455 if (NULL == hb_params)
16456 {
16457 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16458 "%s Request Buffer Alloc Fail", __func__);
16459 return -EINVAL;
16460 }
16461
16462 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070016463 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
16464 hb_params,
16465 wlan_hdd_cfg80211_lphb_ind_handler);
16466 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070016467 {
Leo Changd9df8aa2013-09-26 13:32:26 -070016468 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16469 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070016470 vos_mem_free(hb_params);
16471 }
Leo Chang9056f462013-08-01 19:21:11 -070016472 return 0;
16473 }
16474#endif /* FEATURE_WLAN_LPHB */
16475 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016476 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16477 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070016478 return -EOPNOTSUPP;
16479 }
16480
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016481 EXIT();
16482 return err;
Leo Chang9056f462013-08-01 19:21:11 -070016483}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016484
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053016485static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
16486#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
16487 struct wireless_dev *wdev,
16488#endif
16489 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016490{
16491 int ret;
16492
16493 vos_ssr_protect(__func__);
16494 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
16495 vos_ssr_unprotect(__func__);
16496
16497 return ret;
16498}
Leo Chang9056f462013-08-01 19:21:11 -070016499#endif /* CONFIG_NL80211_TESTMODE */
16500
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016501static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016502 struct net_device *dev,
16503 int idx, struct survey_info *survey)
16504{
16505 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16506 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053016507 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016508 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053016509 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016510 v_S7_t snr,rssi;
16511 int status, i, j, filled = 0;
16512
16513 ENTER();
16514
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016515 if (NULL == pAdapter)
16516 {
16517 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16518 "%s: HDD adapter is Null", __func__);
16519 return -ENODEV;
16520 }
16521
16522 if (NULL == wiphy)
16523 {
16524 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16525 "%s: wiphy is Null", __func__);
16526 return -ENODEV;
16527 }
16528
16529 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16530 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016531 if (0 != status)
16532 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016533 return status;
16534 }
16535
Mihir Sheted9072e02013-08-21 17:02:29 +053016536 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16537
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016538 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053016539 0 != pAdapter->survey_idx ||
16540 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016541 {
16542 /* The survey dump ops when implemented completely is expected to
16543 * return a survey of all channels and the ops is called by the
16544 * kernel with incremental values of the argument 'idx' till it
16545 * returns -ENONET. But we can only support the survey for the
16546 * operating channel for now. survey_idx is used to track
16547 * that the ops is called only once and then return -ENONET for
16548 * the next iteration
16549 */
16550 pAdapter->survey_idx = 0;
16551 return -ENONET;
16552 }
16553
Mukul Sharma9d5233b2015-06-11 20:28:20 +053016554 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
16555 {
16556 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16557 "%s: Roaming in progress, hence return ", __func__);
16558 return -ENONET;
16559 }
16560
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016561 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16562
16563 wlan_hdd_get_snr(pAdapter, &snr);
16564 wlan_hdd_get_rssi(pAdapter, &rssi);
16565
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016566 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16567 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
16568 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016569 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
16570 hdd_wlan_get_freq(channel, &freq);
16571
16572
16573 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
16574 {
16575 if (NULL == wiphy->bands[i])
16576 {
16577 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
16578 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
16579 continue;
16580 }
16581
16582 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
16583 {
16584 struct ieee80211_supported_band *band = wiphy->bands[i];
16585
16586 if (band->channels[j].center_freq == (v_U16_t)freq)
16587 {
16588 survey->channel = &band->channels[j];
16589 /* The Rx BDs contain SNR values in dB for the received frames
16590 * while the supplicant expects noise. So we calculate and
16591 * return the value of noise (dBm)
16592 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
16593 */
16594 survey->noise = rssi - snr;
16595 survey->filled = SURVEY_INFO_NOISE_DBM;
16596 filled = 1;
16597 }
16598 }
16599 }
16600
16601 if (filled)
16602 pAdapter->survey_idx = 1;
16603 else
16604 {
16605 pAdapter->survey_idx = 0;
16606 return -ENONET;
16607 }
16608
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016609 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016610 return 0;
16611}
16612
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016613static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
16614 struct net_device *dev,
16615 int idx, struct survey_info *survey)
16616{
16617 int ret;
16618
16619 vos_ssr_protect(__func__);
16620 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
16621 vos_ssr_unprotect(__func__);
16622
16623 return ret;
16624}
16625
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016626/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016627 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016628 * this is called when cfg80211 driver resume
16629 * driver updates latest sched_scan scan result(if any) to cfg80211 database
16630 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016631int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016632{
16633 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16634 hdd_adapter_t *pAdapter;
16635 hdd_adapter_list_node_t *pAdapterNode, *pNext;
16636 VOS_STATUS status = VOS_STATUS_SUCCESS;
16637
16638 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016639
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016640 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016641 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016642 return 0;
16643 }
16644
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016645 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
16646 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016647 spin_lock(&pHddCtx->schedScan_lock);
16648 pHddCtx->isWiphySuspended = FALSE;
16649 if (TRUE != pHddCtx->isSchedScanUpdatePending)
16650 {
16651 spin_unlock(&pHddCtx->schedScan_lock);
16652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16653 "%s: Return resume is not due to PNO indication", __func__);
16654 return 0;
16655 }
16656 // Reset flag to avoid updatating cfg80211 data old results again
16657 pHddCtx->isSchedScanUpdatePending = FALSE;
16658 spin_unlock(&pHddCtx->schedScan_lock);
16659
16660 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
16661
16662 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
16663 {
16664 pAdapter = pAdapterNode->pAdapter;
16665 if ( (NULL != pAdapter) &&
16666 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
16667 {
16668 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016669 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016670 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
16671 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016672 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016673 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016674 {
16675 /* Acquire wakelock to handle the case where APP's tries to
16676 * suspend immediately after updating the scan results. Whis
16677 * results in app's is in suspended state and not able to
16678 * process the connect request to AP
16679 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053016680 hdd_prevent_suspend_timeout(2000,
16681 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016682 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016683 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016684
16685 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16686 "%s : cfg80211 scan result database updated", __func__);
16687
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016688 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016689 return 0;
16690
16691 }
16692 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16693 pAdapterNode = pNext;
16694 }
16695
16696 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16697 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016698 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016699 return 0;
16700}
16701
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016702int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
16703{
16704 int ret;
16705
16706 vos_ssr_protect(__func__);
16707 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
16708 vos_ssr_unprotect(__func__);
16709
16710 return ret;
16711}
16712
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016713/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016714 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016715 * this is called when cfg80211 driver suspends
16716 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016717int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016718 struct cfg80211_wowlan *wow)
16719{
16720 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016721 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016722
16723 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016724
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016725 ret = wlan_hdd_validate_context(pHddCtx);
16726 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016727 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016728 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016729 }
16730
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016731
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016732 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16733 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
16734 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016735 pHddCtx->isWiphySuspended = TRUE;
16736
16737 EXIT();
16738
16739 return 0;
16740}
16741
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016742int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
16743 struct cfg80211_wowlan *wow)
16744{
16745 int ret;
16746
16747 vos_ssr_protect(__func__);
16748 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
16749 vos_ssr_unprotect(__func__);
16750
16751 return ret;
16752}
Jeff Johnson295189b2012-06-20 16:38:30 -070016753/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016754static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070016755{
16756 .add_virtual_intf = wlan_hdd_add_virtual_intf,
16757 .del_virtual_intf = wlan_hdd_del_virtual_intf,
16758 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
16759 .change_station = wlan_hdd_change_station,
16760#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
16761 .add_beacon = wlan_hdd_cfg80211_add_beacon,
16762 .del_beacon = wlan_hdd_cfg80211_del_beacon,
16763 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016764#else
16765 .start_ap = wlan_hdd_cfg80211_start_ap,
16766 .change_beacon = wlan_hdd_cfg80211_change_beacon,
16767 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070016768#endif
16769 .change_bss = wlan_hdd_cfg80211_change_bss,
16770 .add_key = wlan_hdd_cfg80211_add_key,
16771 .get_key = wlan_hdd_cfg80211_get_key,
16772 .del_key = wlan_hdd_cfg80211_del_key,
16773 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080016774#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070016775 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080016776#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016777 .scan = wlan_hdd_cfg80211_scan,
16778 .connect = wlan_hdd_cfg80211_connect,
16779 .disconnect = wlan_hdd_cfg80211_disconnect,
16780 .join_ibss = wlan_hdd_cfg80211_join_ibss,
16781 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
16782 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
16783 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
16784 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070016785 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
16786 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053016787 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070016788#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16789 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
16790 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
16791 .set_txq_params = wlan_hdd_set_txq_params,
16792#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016793 .get_station = wlan_hdd_cfg80211_get_station,
16794 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
16795 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016796 .add_station = wlan_hdd_cfg80211_add_station,
16797#ifdef FEATURE_WLAN_LFR
16798 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
16799 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
16800 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
16801#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016802#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
16803 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
16804#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016805#ifdef FEATURE_WLAN_TDLS
16806 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
16807 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
16808#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016809#ifdef WLAN_FEATURE_GTK_OFFLOAD
16810 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
16811#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016812#ifdef FEATURE_WLAN_SCAN_PNO
16813 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
16814 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
16815#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016816 .resume = wlan_hdd_cfg80211_resume_wlan,
16817 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016818 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070016819#ifdef WLAN_NL80211_TESTMODE
16820 .testmode_cmd = wlan_hdd_cfg80211_testmode,
16821#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016822 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070016823};
16824