blob: 53ae178609d3680542dd5c312b144601e6f927e7 [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);
1987 int status;
1988
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301989 ENTER();
1990
Sunil Duttc69bccb2014-05-26 21:30:20 +05301991 status = wlan_hdd_validate_context(pHddCtx);
1992 if (0 != status)
1993 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301994 return -EINVAL ;
1995 }
1996
1997 if (NULL == pAdapter)
1998 {
1999 hddLog(VOS_TRACE_LEVEL_FATAL,
2000 "%s: HDD adapter is Null", __func__);
2001 return -ENODEV;
2002 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302003 /* check the LLStats Capability */
2004 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2005 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2006 {
2007 hddLog(VOS_TRACE_LEVEL_ERROR,
2008 FL("Link Layer Statistics not supported by Firmware"));
2009 return -EINVAL;
2010 }
2011
Sunil Duttc69bccb2014-05-26 21:30:20 +05302012
2013 if (!pAdapter->isLinkLayerStatsSet)
2014 {
2015 hddLog(VOS_TRACE_LEVEL_FATAL,
2016 "%s: isLinkLayerStatsSet : %d",
2017 __func__, pAdapter->isLinkLayerStatsSet);
2018 return -EINVAL;
2019 }
2020
2021 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2022 (struct nlattr *)data,
2023 data_len, qca_wlan_vendor_ll_get_policy))
2024 {
2025 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2026 return -EINVAL;
2027 }
2028
2029 if (!tb_vendor
2030 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2031 {
2032 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2033 return -EINVAL;
2034 }
2035
2036 if (!tb_vendor
2037 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2038 {
2039 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2040 return -EINVAL;
2041 }
2042
Sunil Duttc69bccb2014-05-26 21:30:20 +05302043
Dino Mycledf0a5d92014-07-04 09:41:55 +05302044 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302045 nla_get_u32( tb_vendor[
2046 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302047 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302048 nla_get_u32( tb_vendor[
2049 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2050
Dino Mycled3d50022014-07-07 12:58:25 +05302051 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2052 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302053
2054 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302055 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302056 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302057 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302058 hddLog(VOS_TRACE_LEVEL_INFO,
2059 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302060 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302061
2062 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302063 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302064 {
2065 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2066 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302067 return -EINVAL;
2068 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302069
2070 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302071 return 0;
2072}
2073
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302074static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2075 struct wireless_dev *wdev,
2076 const void *data,
2077 int data_len)
2078{
2079 int ret = 0;
2080
2081 vos_ssr_protect(__func__);
2082 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
2083 vos_ssr_unprotect(__func__);
2084
2085 return ret;
2086}
2087
Sunil Duttc69bccb2014-05-26 21:30:20 +05302088const struct
2089nla_policy
2090qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
2091{
2092 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
2093 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
2094 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
2095 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
2096};
2097
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302098static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2099 struct wireless_dev *wdev,
2100 const void *data,
2101 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302102{
2103 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2104 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302105 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302106 struct net_device *dev = wdev->netdev;
2107 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2108 u32 statsClearReqMask;
2109 u8 stopReq;
2110 int status;
2111
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302112 ENTER();
2113
Sunil Duttc69bccb2014-05-26 21:30:20 +05302114 status = wlan_hdd_validate_context(pHddCtx);
2115 if (0 != status)
2116 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302117 return -EINVAL;
2118 }
2119
2120 if (NULL == pAdapter)
2121 {
2122 hddLog(VOS_TRACE_LEVEL_FATAL,
2123 "%s: HDD adapter is Null", __func__);
2124 return -ENODEV;
2125 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302126 /* check the LLStats Capability */
2127 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2128 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2129 {
2130 hddLog(VOS_TRACE_LEVEL_ERROR,
2131 FL("Enable LLStats Capability"));
2132 return -EINVAL;
2133 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302134
2135 if (!pAdapter->isLinkLayerStatsSet)
2136 {
2137 hddLog(VOS_TRACE_LEVEL_FATAL,
2138 "%s: isLinkLayerStatsSet : %d",
2139 __func__, pAdapter->isLinkLayerStatsSet);
2140 return -EINVAL;
2141 }
2142
2143 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2144 (struct nlattr *)data,
2145 data_len, qca_wlan_vendor_ll_clr_policy))
2146 {
2147 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2148 return -EINVAL;
2149 }
2150
2151 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2152
2153 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2154 {
2155 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2156 return -EINVAL;
2157
2158 }
2159
Sunil Duttc69bccb2014-05-26 21:30:20 +05302160
Dino Mycledf0a5d92014-07-04 09:41:55 +05302161 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302162 nla_get_u32(
2163 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2164
Dino Mycledf0a5d92014-07-04 09:41:55 +05302165 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302166 nla_get_u8(
2167 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2168
2169 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302170 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302171
Dino Mycled3d50022014-07-07 12:58:25 +05302172 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2173 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302174
2175 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302176 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302177 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302178 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302179 hddLog(VOS_TRACE_LEVEL_INFO,
2180 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302181 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302182 hddLog(VOS_TRACE_LEVEL_INFO,
2183 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302184 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302185
2186 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302187 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302188 {
2189 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302190 hdd_station_ctx_t *pHddStaCtx;
2191
2192 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2193 if (VOS_STATUS_SUCCESS !=
2194 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2195 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2196 {
2197 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2198 "WLANTL_ClearInterfaceStats Failed", __func__);
2199 return -EINVAL;
2200 }
2201 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2202 (statsClearReqMask & WIFI_STATS_IFACE)) {
2203 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2204 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2205 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2206 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2207 }
2208
Sunil Duttc69bccb2014-05-26 21:30:20 +05302209 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2210 2 * sizeof(u32) +
2211 NLMSG_HDRLEN);
2212
2213 if (temp_skbuff != NULL)
2214 {
2215
2216 if (nla_put_u32(temp_skbuff,
2217 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2218 statsClearReqMask) ||
2219 nla_put_u32(temp_skbuff,
2220 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2221 stopReq))
2222 {
2223 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2224 kfree_skb(temp_skbuff);
2225 return -EINVAL;
2226 }
2227 /* If the ask is to stop the stats collection as part of clear
2228 * (stopReq = 1) , ensure that no further requests of get
2229 * go to the firmware by having isLinkLayerStatsSet set to 0.
2230 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302231 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302232 * case the firmware is just asked to clear the statistics.
2233 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302234 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302235 pAdapter->isLinkLayerStatsSet = 0;
2236 return cfg80211_vendor_cmd_reply(temp_skbuff);
2237 }
2238 return -ENOMEM;
2239 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302240
2241 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302242 return -EINVAL;
2243}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302244static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2245 struct wireless_dev *wdev,
2246 const void *data,
2247 int data_len)
2248{
2249 int ret = 0;
2250
2251 vos_ssr_protect(__func__);
2252 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2253 vos_ssr_unprotect(__func__);
2254
2255 return ret;
2256
2257
2258}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302259#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2260
Dino Mycle6fb96c12014-06-10 11:52:40 +05302261#ifdef WLAN_FEATURE_EXTSCAN
2262static const struct nla_policy
2263wlan_hdd_extscan_config_policy
2264 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2265{
2266 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2267 { .type = NLA_U32 },
2268 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2269 { .type = NLA_U32 },
2270 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2271 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2272 { .type = NLA_U32 },
2273 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2274 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2275
2276 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2277 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2278 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2279 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2280 { .type = NLA_U8 },
2281 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2282 { .type = NLA_U32 },
2283 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2284 { .type = NLA_U32 },
2285 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2286 { .type = NLA_U32 },
2287 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
2288 { .type = NLA_U8 },
2289 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2290 { .type = NLA_U8 },
2291 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2292 { .type = NLA_U8 },
2293
2294 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2295 { .type = NLA_U32 },
2296 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2297 { .type = NLA_UNSPEC },
2298 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2299 { .type = NLA_S32 },
2300 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2301 { .type = NLA_S32 },
2302 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2303 { .type = NLA_U32 },
2304 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2305 { .type = NLA_U32 },
2306 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
2307 { .type = NLA_U32 },
2308 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
2309 = { .type = NLA_U32 },
2310 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
2311 { .type = NLA_U32 },
2312 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
2313 NLA_U32 },
2314};
2315
2316static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
2317{
2318 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2319 struct sk_buff *skb = NULL;
2320 tpSirEXTScanCapabilitiesEvent pData =
2321 (tpSirEXTScanCapabilitiesEvent) pMsg;
2322
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302323 ENTER();
2324
2325 if (wlan_hdd_validate_context(pHddCtx))
2326 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302327 return;
2328 }
2329
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302330 if (!pMsg)
2331 {
2332 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2333 return;
2334 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302335 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302336#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2337 NULL,
2338#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302339 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2340 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
2341 GFP_KERNEL);
2342
2343 if (!skb) {
2344 hddLog(VOS_TRACE_LEVEL_ERROR,
2345 FL("cfg80211_vendor_event_alloc failed"));
2346 return;
2347 }
2348
2349 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2350 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
2351 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
2352 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
2353 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
2354 pData->maxRssiSampleSize);
2355 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
2356 pData->maxScanReportingThreshold);
2357 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
2358 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
2359 pData->maxSignificantWifiChangeAPs);
2360 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
2361 pData->maxBsidHistoryEntries);
2362
2363 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2364 pData->requestId) ||
2365 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
2366 nla_put_u32(skb,
2367 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
2368 pData->scanCacheSize) ||
2369 nla_put_u32(skb,
2370 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
2371 pData->scanBuckets) ||
2372 nla_put_u32(skb,
2373 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
2374 pData->maxApPerScan) ||
2375 nla_put_u32(skb,
2376 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
2377 pData->maxRssiSampleSize) ||
2378 nla_put_u32(skb,
2379 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
2380 pData->maxScanReportingThreshold) ||
2381 nla_put_u32(skb,
2382 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
2383 pData->maxHotlistAPs) ||
2384 nla_put_u32(skb,
2385 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
2386 pData->maxSignificantWifiChangeAPs) ||
2387 nla_put_u32(skb,
2388 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
2389 pData->maxBsidHistoryEntries)) {
2390 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2391 goto nla_put_failure;
2392 }
2393
2394 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302395 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302396 return;
2397
2398nla_put_failure:
2399 kfree_skb(skb);
2400 return;
2401}
2402
2403
2404static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2405{
2406 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2407 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2408 struct sk_buff *skb = NULL;
2409 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2410
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302411 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302412
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302413 if (wlan_hdd_validate_context(pHddCtx)){
2414 return;
2415 }
2416 if (!pMsg)
2417 {
2418 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302419 return;
2420 }
2421
2422 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302423#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2424 NULL,
2425#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302426 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2427 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2428 GFP_KERNEL);
2429
2430 if (!skb) {
2431 hddLog(VOS_TRACE_LEVEL_ERROR,
2432 FL("cfg80211_vendor_event_alloc failed"));
2433 return;
2434 }
2435 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2436 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2437 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2438
2439 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2440 pData->requestId) ||
2441 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2442 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2443 goto nla_put_failure;
2444 }
2445
2446 /*
2447 * Store the Request ID for comparing with the requestID obtained
2448 * in other requests.HDD shall return a failure is the extscan_stop
2449 * request is issued with a different requestId as that of the
2450 * extscan_start request. Also, This requestId shall be used while
2451 * indicating the full scan results to the upper layers.
2452 * The requestId is stored with the assumption that the firmware
2453 * shall return the ext scan start request's requestId in ext scan
2454 * start response.
2455 */
2456 if (pData->status == 0)
2457 pMac->sme.extScanStartReqId = pData->requestId;
2458
2459
2460 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302461 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302462 return;
2463
2464nla_put_failure:
2465 kfree_skb(skb);
2466 return;
2467}
2468
2469
2470static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2471{
2472 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2473 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2474 struct sk_buff *skb = NULL;
2475
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302476 ENTER();
2477
2478 if (wlan_hdd_validate_context(pHddCtx)){
2479 return;
2480 }
2481 if (!pMsg)
2482 {
2483 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302484 return;
2485 }
2486
2487 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302488#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2489 NULL,
2490#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302491 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2492 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2493 GFP_KERNEL);
2494
2495 if (!skb) {
2496 hddLog(VOS_TRACE_LEVEL_ERROR,
2497 FL("cfg80211_vendor_event_alloc failed"));
2498 return;
2499 }
2500 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2501 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2502
2503 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2504 pData->requestId) ||
2505 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2506 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2507 goto nla_put_failure;
2508 }
2509
2510 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302511 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302512 return;
2513
2514nla_put_failure:
2515 kfree_skb(skb);
2516 return;
2517}
2518
2519
2520static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2521 void *pMsg)
2522{
2523 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2524 struct sk_buff *skb = NULL;
2525 tpSirEXTScanSetBssidHotListRspParams pData =
2526 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2527
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302528 ENTER();
2529
2530 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302531 return;
2532 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302533 if (!pMsg)
2534 {
2535 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2536 return;
2537 }
2538
Dino Mycle6fb96c12014-06-10 11:52:40 +05302539 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302540#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2541 NULL,
2542#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302543 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2544 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2545 GFP_KERNEL);
2546
2547 if (!skb) {
2548 hddLog(VOS_TRACE_LEVEL_ERROR,
2549 FL("cfg80211_vendor_event_alloc failed"));
2550 return;
2551 }
2552 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2553 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2554 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2555
2556 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2557 pData->requestId) ||
2558 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2559 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2560 goto nla_put_failure;
2561 }
2562
2563 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302564 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302565 return;
2566
2567nla_put_failure:
2568 kfree_skb(skb);
2569 return;
2570}
2571
2572static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2573 void *pMsg)
2574{
2575 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2576 struct sk_buff *skb = NULL;
2577 tpSirEXTScanResetBssidHotlistRspParams pData =
2578 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2579
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302580 ENTER();
2581
2582 if (wlan_hdd_validate_context(pHddCtx)) {
2583 return;
2584 }
2585 if (!pMsg)
2586 {
2587 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302588 return;
2589 }
2590
2591 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302592#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2593 NULL,
2594#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302595 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2596 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2597 GFP_KERNEL);
2598
2599 if (!skb) {
2600 hddLog(VOS_TRACE_LEVEL_ERROR,
2601 FL("cfg80211_vendor_event_alloc failed"));
2602 return;
2603 }
2604 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2605 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2606
2607 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2608 pData->requestId) ||
2609 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2610 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2611 goto nla_put_failure;
2612 }
2613
2614 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302615 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302616 return;
2617
2618nla_put_failure:
2619 kfree_skb(skb);
2620 return;
2621}
2622
2623
2624static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2625 void *pMsg)
2626{
2627 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2628 struct sk_buff *skb = NULL;
2629 tpSirEXTScanSetSignificantChangeRspParams pData =
2630 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2631
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302632 ENTER();
2633
2634 if (wlan_hdd_validate_context(pHddCtx)) {
2635 return;
2636 }
2637 if (!pMsg)
2638 {
2639 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302640 return;
2641 }
2642
2643 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302644#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2645 NULL,
2646#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302647 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2648 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2649 GFP_KERNEL);
2650
2651 if (!skb) {
2652 hddLog(VOS_TRACE_LEVEL_ERROR,
2653 FL("cfg80211_vendor_event_alloc failed"));
2654 return;
2655 }
2656 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2657 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2658 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2659
2660 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2661 pData->requestId) ||
2662 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2663 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2664 goto nla_put_failure;
2665 }
2666
2667 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302668 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302669 return;
2670
2671nla_put_failure:
2672 kfree_skb(skb);
2673 return;
2674}
2675
2676
2677static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2678 void *pMsg)
2679{
2680 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2681 struct sk_buff *skb = NULL;
2682 tpSirEXTScanResetSignificantChangeRspParams pData =
2683 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2684
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302685 ENTER();
2686
2687 if (wlan_hdd_validate_context(pHddCtx)) {
2688 return;
2689 }
2690 if (!pMsg)
2691 {
2692 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302693 return;
2694 }
2695
2696 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302697#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2698 NULL,
2699#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302700 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2701 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2702 GFP_KERNEL);
2703
2704 if (!skb) {
2705 hddLog(VOS_TRACE_LEVEL_ERROR,
2706 FL("cfg80211_vendor_event_alloc failed"));
2707 return;
2708 }
2709 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2710 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2711 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2712
2713 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2714 pData->requestId) ||
2715 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2716 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2717 goto nla_put_failure;
2718 }
2719
2720 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302721 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302722 return;
2723
2724nla_put_failure:
2725 kfree_skb(skb);
2726 return;
2727}
2728
2729static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2730 void *pMsg)
2731{
2732 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2733 struct sk_buff *skb = NULL;
2734 tANI_U32 i = 0, j, resultsPerEvent;
2735 tANI_S32 totalResults;
2736 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2737 tpSirWifiScanResult pSirWifiScanResult;
2738
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302739 ENTER();
2740
2741 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302742 return;
2743 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302744 if (!pMsg)
2745 {
2746 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2747 return;
2748 }
2749
Dino Mycle6fb96c12014-06-10 11:52:40 +05302750 totalResults = pData->numOfAps;
2751 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2752 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2753 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2754
2755 do{
2756 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2757 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2758 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2759
2760 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302761#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2762 NULL,
2763#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302764 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2765 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2766 GFP_KERNEL);
2767
2768 if (!skb) {
2769 hddLog(VOS_TRACE_LEVEL_ERROR,
2770 FL("cfg80211_vendor_event_alloc failed"));
2771 return;
2772 }
2773
2774 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2775
2776 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2777 pData->requestId) ||
2778 nla_put_u32(skb,
2779 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2780 resultsPerEvent)) {
2781 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2782 goto fail;
2783 }
2784 if (nla_put_u8(skb,
2785 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2786 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2787 {
2788 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2789 goto fail;
2790 }
2791
2792 if (resultsPerEvent) {
2793 struct nlattr *aps;
2794
2795 aps = nla_nest_start(skb,
2796 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2797 if (!aps)
2798 {
2799 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2800 goto fail;
2801 }
2802
2803 for (j = 0; j < resultsPerEvent; j++, i++) {
2804 struct nlattr *ap;
2805 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2806 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2807
2808 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2809 "Ssid (%s)"
2810 "Bssid: %pM "
2811 "Channel (%u)"
2812 "Rssi (%d)"
2813 "RTT (%u)"
2814 "RTT_SD (%u)",
2815 i,
2816 pSirWifiScanResult->ts,
2817 pSirWifiScanResult->ssid,
2818 pSirWifiScanResult->bssid,
2819 pSirWifiScanResult->channel,
2820 pSirWifiScanResult->rssi,
2821 pSirWifiScanResult->rtt,
2822 pSirWifiScanResult->rtt_sd);
2823
2824 ap = nla_nest_start(skb, j + 1);
2825 if (!ap)
2826 {
2827 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2828 goto fail;
2829 }
2830
2831 if (nla_put_u64(skb,
2832 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2833 pSirWifiScanResult->ts) )
2834 {
2835 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2836 goto fail;
2837 }
2838 if (nla_put(skb,
2839 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2840 sizeof(pSirWifiScanResult->ssid),
2841 pSirWifiScanResult->ssid) )
2842 {
2843 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2844 goto fail;
2845 }
2846 if (nla_put(skb,
2847 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2848 sizeof(pSirWifiScanResult->bssid),
2849 pSirWifiScanResult->bssid) )
2850 {
2851 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2852 goto fail;
2853 }
2854 if (nla_put_u32(skb,
2855 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2856 pSirWifiScanResult->channel) )
2857 {
2858 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2859 goto fail;
2860 }
Dasari Srinivas90747d72014-10-08 12:16:15 +05302861 if (nla_put_s32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302862 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2863 pSirWifiScanResult->rssi) )
2864 {
2865 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2866 goto fail;
2867 }
2868 if (nla_put_u32(skb,
2869 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2870 pSirWifiScanResult->rtt) )
2871 {
2872 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2873 goto fail;
2874 }
2875 if (nla_put_u32(skb,
2876 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2877 pSirWifiScanResult->rtt_sd))
2878 {
2879 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2880 goto fail;
2881 }
2882
2883 nla_nest_end(skb, ap);
2884 }
2885 nla_nest_end(skb, aps);
2886
2887 }
2888 cfg80211_vendor_event(skb, GFP_KERNEL);
2889 } while (totalResults > 0);
2890
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302891 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302892 return;
2893fail:
2894 kfree_skb(skb);
2895 return;
2896}
2897
2898static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2899 void *pMsg)
2900{
2901 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2902 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2903 struct sk_buff *skb = NULL;
2904 tANI_U32 i;
2905
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302906 ENTER();
2907
2908 if (wlan_hdd_validate_context(pHddCtx)) {
2909 return;
2910 }
2911 if (!pMsg)
2912 {
2913 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302914 return;
2915 }
2916
2917 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302918#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2919 NULL,
2920#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302921 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2922 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2923 GFP_KERNEL);
2924
2925 if (!skb) {
2926 hddLog(VOS_TRACE_LEVEL_ERROR,
2927 FL("cfg80211_vendor_event_alloc failed"));
2928 return;
2929 }
2930 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2931 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2932 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2933 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2934
2935 for (i = 0; i < pData->numOfAps; i++) {
2936 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2937 "Ssid (%s) "
2938 "Bssid (" MAC_ADDRESS_STR ") "
2939 "Channel (%u) "
2940 "Rssi (%d) "
2941 "RTT (%u) "
2942 "RTT_SD (%u) ",
2943 i,
2944 pData->ap[i].ts,
2945 pData->ap[i].ssid,
2946 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2947 pData->ap[i].channel,
2948 pData->ap[i].rssi,
2949 pData->ap[i].rtt,
2950 pData->ap[i].rtt_sd);
2951 }
2952
2953 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2954 pData->requestId) ||
2955 nla_put_u32(skb,
2956 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2957 pData->numOfAps)) {
2958 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2959 goto fail;
2960 }
2961 if (pData->numOfAps) {
2962 struct nlattr *aps;
2963
2964 aps = nla_nest_start(skb,
2965 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2966 if (!aps)
2967 goto fail;
2968
2969 for (i = 0; i < pData->numOfAps; i++) {
2970 struct nlattr *ap;
2971
2972 ap = nla_nest_start(skb, i + 1);
2973 if (!ap)
2974 goto fail;
2975
2976 if (nla_put_u64(skb,
2977 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2978 pData->ap[i].ts) ||
2979 nla_put(skb,
2980 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2981 sizeof(pData->ap[i].ssid),
2982 pData->ap[i].ssid) ||
2983 nla_put(skb,
2984 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2985 sizeof(pData->ap[i].bssid),
2986 pData->ap[i].bssid) ||
2987 nla_put_u32(skb,
2988 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2989 pData->ap[i].channel) ||
2990 nla_put_s32(skb,
2991 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2992 pData->ap[i].rssi) ||
2993 nla_put_u32(skb,
2994 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2995 pData->ap[i].rtt) ||
2996 nla_put_u32(skb,
2997 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2998 pData->ap[i].rtt_sd))
2999 goto fail;
3000
3001 nla_nest_end(skb, ap);
3002 }
3003 nla_nest_end(skb, aps);
3004
3005 if (nla_put_u8(skb,
3006 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3007 pData->moreData))
3008 goto fail;
3009 }
3010
3011 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303012 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303013 return;
3014
3015fail:
3016 kfree_skb(skb);
3017 return;
3018
3019}
3020static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
3021 void *pMsg)
3022{
3023 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3024 struct sk_buff *skb = NULL;
3025 tANI_U32 i, j;
3026 tpSirWifiSignificantChangeEvent pData =
3027 (tpSirWifiSignificantChangeEvent) pMsg;
3028
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303029 ENTER();
3030
3031 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303032 return;
3033 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303034 if (!pMsg)
3035 {
3036 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3037 return;
3038 }
3039
Dino Mycle6fb96c12014-06-10 11:52:40 +05303040 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303041#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3042 NULL,
3043#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303044 EXTSCAN_EVENT_BUF_SIZE,
3045 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
3046 GFP_KERNEL);
3047
3048 if (!skb) {
3049 hddLog(VOS_TRACE_LEVEL_ERROR,
3050 FL("cfg80211_vendor_event_alloc failed"));
3051 return;
3052 }
3053 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3054 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3055 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
3056 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
3057 pData->numSigRssiBss);
3058 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
3059
3060 for (i = 0; i < pData->numSigRssiBss; i++) {
3061 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
3062 " num RSSI %u ",
3063 i, pData->sigRssiResult[i].bssid,
3064 pData->sigRssiResult[i].channel,
3065 pData->sigRssiResult[i].numRssi);
3066
3067 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
3068
3069 hddLog(VOS_TRACE_LEVEL_INFO,
3070 " [%d]",
Dino Myclec8f3f332014-07-21 16:48:27 +05303071 pData->sigRssiResult[i].rssi[j]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303072
3073 }
3074 }
3075
3076
3077 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3078 pData->requestId) ||
3079 nla_put_u32(skb,
3080 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3081 pData->numSigRssiBss)) {
3082 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3083 goto fail;
3084 }
3085
3086 if (pData->numSigRssiBss) {
3087 struct nlattr *aps;
3088 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3089 if (!aps)
3090 goto fail;
3091 for (i = 0; i < pData->numSigRssiBss; i++) {
3092 struct nlattr *ap;
3093
3094 ap = nla_nest_start(skb, i);
3095 if (!ap)
3096 goto fail;
3097 if (nla_put(skb,
3098 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
3099 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
3100 nla_put_u32(skb,
3101 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
3102 pData->sigRssiResult[i].channel) ||
3103 nla_put_u32(skb,
3104 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
3105 pData->sigRssiResult[i].numRssi) ||
3106 nla_put(skb,
3107 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
3108 sizeof(s32) * pData->sigRssiResult[i].numRssi,
3109 pData->sigRssiResult[i].rssi))
3110 goto fail;
3111 nla_nest_end(skb, ap);
3112 }
3113 nla_nest_end(skb, aps);
3114 if (nla_put_u8(skb,
3115 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3116 pData->moreData))
3117 goto fail;
3118 }
3119 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303120 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303121 return;
3122fail:
3123 kfree_skb(skb);
3124 return;
3125}
3126
3127static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3128 void *pMsg)
3129{
3130 struct sk_buff *skb;
3131 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3132 tpSirWifiFullScanResultEvent pData =
3133 (tpSirWifiFullScanResultEvent) (pMsg);
3134
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303135 ENTER();
3136
3137 if (wlan_hdd_validate_context(pHddCtx)) {
3138 return;
3139 }
3140 if (!pMsg)
3141 {
3142 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303143 return;
3144 }
3145
3146 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303147#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3148 NULL,
3149#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303150 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3151 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3152 GFP_KERNEL);
3153
3154 if (!skb) {
3155 hddLog(VOS_TRACE_LEVEL_ERROR,
3156 FL("cfg80211_vendor_event_alloc failed"));
3157 return;
3158 }
3159
3160 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3161 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3162 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3163 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3164 "Ssid (%s)"
3165 "Bssid (" MAC_ADDRESS_STR ")"
3166 "Channel (%u)"
3167 "Rssi (%d)"
3168 "RTT (%u)"
3169 "RTT_SD (%u)"),
3170 pData->ap.ts,
3171 pData->ap.ssid,
3172 MAC_ADDR_ARRAY(pData->ap.bssid),
3173 pData->ap.channel,
3174 pData->ap.rssi,
3175 pData->ap.rtt,
3176 pData->ap.rtt_sd);
3177 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3178 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3179 pData->requestId) ||
3180 nla_put_u64(skb,
3181 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3182 pData->ap.ts) ||
3183 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3184 sizeof(pData->ap.ssid),
3185 pData->ap.ssid) ||
3186 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3187 WNI_CFG_BSSID_LEN,
3188 pData->ap.bssid) ||
3189 nla_put_u32(skb,
3190 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3191 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303192 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303193 pData->ap.rssi) ||
3194 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3195 pData->ap.rtt) ||
3196 nla_put_u32(skb,
3197 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3198 pData->ap.rtt_sd) ||
3199 nla_put_u16(skb,
3200 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3201 pData->ap.beaconPeriod) ||
3202 nla_put_u16(skb,
3203 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3204 pData->ap.capability) ||
3205 nla_put_u32(skb,
3206 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3207 pData->ieLength))
3208 {
3209 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3210 goto nla_put_failure;
3211 }
3212 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3213 pData->ieLength,
3214 pData->ie))
3215 {
3216 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3217 goto nla_put_failure;
3218 }
3219
3220 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303221 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303222 return;
3223
3224nla_put_failure:
3225 kfree_skb(skb);
3226 return;
3227}
3228
3229static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3230 void *pMsg)
3231{
3232 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3233 struct sk_buff *skb = NULL;
3234 tpSirEXTScanResultsAvailableIndParams pData =
3235 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3236
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303237 ENTER();
3238
3239 if (wlan_hdd_validate_context(pHddCtx)){
3240 return;
3241 }
3242 if (!pMsg)
3243 {
3244 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303245 return;
3246 }
3247
3248 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303249#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3250 NULL,
3251#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303252 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3253 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3254 GFP_KERNEL);
3255
3256 if (!skb) {
3257 hddLog(VOS_TRACE_LEVEL_ERROR,
3258 FL("cfg80211_vendor_event_alloc failed"));
3259 return;
3260 }
3261
3262 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3263 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3264 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3265 pData->numResultsAvailable);
3266 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3267 pData->requestId) ||
3268 nla_put_u32(skb,
3269 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3270 pData->numResultsAvailable)) {
3271 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3272 goto nla_put_failure;
3273 }
3274
3275 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303276 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303277 return;
3278
3279nla_put_failure:
3280 kfree_skb(skb);
3281 return;
3282}
3283
3284static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3285{
3286 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3287 struct sk_buff *skb = NULL;
3288 tpSirEXTScanProgressIndParams pData =
3289 (tpSirEXTScanProgressIndParams) pMsg;
3290
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303291 ENTER();
3292
3293 if (wlan_hdd_validate_context(pHddCtx)){
3294 return;
3295 }
3296 if (!pMsg)
3297 {
3298 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303299 return;
3300 }
3301
3302 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303303#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3304 NULL,
3305#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303306 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3307 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3308 GFP_KERNEL);
3309
3310 if (!skb) {
3311 hddLog(VOS_TRACE_LEVEL_ERROR,
3312 FL("cfg80211_vendor_event_alloc failed"));
3313 return;
3314 }
3315 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3316 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3317 pData->extScanEventType);
3318 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3319 pData->status);
3320
3321 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3322 pData->extScanEventType) ||
3323 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303324 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3325 pData->requestId) ||
3326 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303327 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3328 pData->status)) {
3329 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3330 goto nla_put_failure;
3331 }
3332
3333 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303334 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303335 return;
3336
3337nla_put_failure:
3338 kfree_skb(skb);
3339 return;
3340}
3341
3342void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3343 void *pMsg)
3344{
3345 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3346
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303347 ENTER();
3348
Dino Mycle6fb96c12014-06-10 11:52:40 +05303349 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303350 return;
3351 }
3352
3353 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3354
3355
3356 switch(evType) {
3357 case SIR_HAL_EXTSCAN_START_RSP:
3358 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3359 break;
3360
3361 case SIR_HAL_EXTSCAN_STOP_RSP:
3362 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3363 break;
3364 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3365 /* There is no need to send this response to upper layer
3366 Just log the message */
3367 hddLog(VOS_TRACE_LEVEL_INFO,
3368 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3369 break;
3370 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3371 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3372 break;
3373
3374 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3375 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3376 break;
3377
3378 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
3379 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
3380 break;
3381
3382 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
3383 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
3384 break;
3385 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
3386 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
3387 break;
3388 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3389 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3390 break;
3391 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3392 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3393 break;
3394 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3395 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3396 break;
3397 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3398 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3399 break;
3400 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
3401 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
3402 break;
3403 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3404 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3405 break;
3406 default:
3407 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3408 break;
3409 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303410 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303411}
3412
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303413static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3414 struct wireless_dev *wdev,
3415 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303416{
Dino Myclee8843b32014-07-04 14:21:45 +05303417 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303418 struct net_device *dev = wdev->netdev;
3419 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3420 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3421 struct nlattr
3422 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3423 eHalStatus status;
3424
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303425 ENTER();
3426
Dino Mycle6fb96c12014-06-10 11:52:40 +05303427 status = wlan_hdd_validate_context(pHddCtx);
3428 if (0 != status)
3429 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303430 return -EINVAL;
3431 }
Dino Myclee8843b32014-07-04 14:21:45 +05303432 /* check the EXTScan Capability */
3433 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3434 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3435 {
3436 hddLog(VOS_TRACE_LEVEL_ERROR,
3437 FL("EXTScan not enabled/supported by Firmware"));
3438 return -EINVAL;
3439 }
3440
Dino Mycle6fb96c12014-06-10 11:52:40 +05303441 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3442 data, dataLen,
3443 wlan_hdd_extscan_config_policy)) {
3444 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3445 return -EINVAL;
3446 }
3447
3448 /* Parse and fetch request Id */
3449 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3450 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3451 return -EINVAL;
3452 }
3453
Dino Mycle6fb96c12014-06-10 11:52:40 +05303454
Dino Myclee8843b32014-07-04 14:21:45 +05303455 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303456 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303457 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303458
Dino Myclee8843b32014-07-04 14:21:45 +05303459 reqMsg.sessionId = pAdapter->sessionId;
3460 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303461
Dino Myclee8843b32014-07-04 14:21:45 +05303462 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303463 if (!HAL_STATUS_SUCCESS(status)) {
3464 hddLog(VOS_TRACE_LEVEL_ERROR,
3465 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303466 return -EINVAL;
3467 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303468 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303469 return 0;
3470}
3471
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303472static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3473 struct wireless_dev *wdev,
3474 const void *data, int dataLen)
3475{
3476 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303477
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303478 vos_ssr_protect(__func__);
3479 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3480 vos_ssr_unprotect(__func__);
3481
3482 return ret;
3483}
3484
3485static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3486 struct wireless_dev *wdev,
3487 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303488{
Dino Myclee8843b32014-07-04 14:21:45 +05303489 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303490 struct net_device *dev = wdev->netdev;
3491 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3492 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3493 struct nlattr
3494 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3495 eHalStatus status;
3496
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303497 ENTER();
3498
Dino Mycle6fb96c12014-06-10 11:52:40 +05303499 status = wlan_hdd_validate_context(pHddCtx);
3500 if (0 != status)
3501 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303502 return -EINVAL;
3503 }
Dino Myclee8843b32014-07-04 14:21:45 +05303504 /* check the EXTScan Capability */
3505 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3506 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3507 {
3508 hddLog(VOS_TRACE_LEVEL_ERROR,
3509 FL("EXTScan not enabled/supported by Firmware"));
3510 return -EINVAL;
3511 }
3512
Dino Mycle6fb96c12014-06-10 11:52:40 +05303513 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3514 data, dataLen,
3515 wlan_hdd_extscan_config_policy)) {
3516 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3517 return -EINVAL;
3518 }
3519 /* Parse and fetch request Id */
3520 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3521 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3522 return -EINVAL;
3523 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303524
Dino Myclee8843b32014-07-04 14:21:45 +05303525 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303526 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3527
Dino Myclee8843b32014-07-04 14:21:45 +05303528 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303529
Dino Myclee8843b32014-07-04 14:21:45 +05303530 reqMsg.sessionId = pAdapter->sessionId;
3531 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303532
3533 /* Parse and fetch flush parameter */
3534 if (!tb
3535 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3536 {
3537 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3538 goto failed;
3539 }
Dino Myclee8843b32014-07-04 14:21:45 +05303540 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303541 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3542
Dino Myclee8843b32014-07-04 14:21:45 +05303543 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303544
Dino Myclee8843b32014-07-04 14:21:45 +05303545 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303546 if (!HAL_STATUS_SUCCESS(status)) {
3547 hddLog(VOS_TRACE_LEVEL_ERROR,
3548 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303549 return -EINVAL;
3550 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303551 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303552 return 0;
3553
3554failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303555 return -EINVAL;
3556}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303557static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3558 struct wireless_dev *wdev,
3559 const void *data, int dataLen)
3560{
3561 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303562
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303563 vos_ssr_protect(__func__);
3564 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3565 vos_ssr_unprotect(__func__);
3566
3567 return ret;
3568}
3569
3570static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303571 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303572 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303573{
3574 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3575 struct net_device *dev = wdev->netdev;
3576 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3577 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3578 struct nlattr
3579 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3580 struct nlattr
3581 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3582 struct nlattr *apTh;
3583 eHalStatus status;
3584 tANI_U8 i = 0;
3585 int rem;
3586
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303587 ENTER();
3588
Dino Mycle6fb96c12014-06-10 11:52:40 +05303589 status = wlan_hdd_validate_context(pHddCtx);
3590 if (0 != status)
3591 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303592 return -EINVAL;
3593 }
Dino Myclee8843b32014-07-04 14:21:45 +05303594 /* check the EXTScan Capability */
3595 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3596 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3597 {
3598 hddLog(VOS_TRACE_LEVEL_ERROR,
3599 FL("EXTScan not enabled/supported by Firmware"));
3600 return -EINVAL;
3601 }
3602
Dino Mycle6fb96c12014-06-10 11:52:40 +05303603 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3604 data, dataLen,
3605 wlan_hdd_extscan_config_policy)) {
3606 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3607 return -EINVAL;
3608 }
3609
3610 /* Parse and fetch request Id */
3611 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3612 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3613 return -EINVAL;
3614 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303615 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3616 vos_mem_malloc(sizeof(*pReqMsg));
3617 if (!pReqMsg) {
3618 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3619 return -ENOMEM;
3620 }
3621
Dino Myclee8843b32014-07-04 14:21:45 +05303622
Dino Mycle6fb96c12014-06-10 11:52:40 +05303623 pReqMsg->requestId = nla_get_u32(
3624 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3625 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3626
3627 /* Parse and fetch number of APs */
3628 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3629 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3630 goto fail;
3631 }
3632
3633 pReqMsg->sessionId = pAdapter->sessionId;
3634 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3635
3636 pReqMsg->numAp = nla_get_u32(
3637 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3638 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3639
3640 nla_for_each_nested(apTh,
3641 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3642 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3643 nla_data(apTh), nla_len(apTh),
3644 NULL)) {
3645 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3646 goto fail;
3647 }
3648
3649 /* Parse and fetch MAC address */
3650 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3651 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3652 goto fail;
3653 }
3654 memcpy(pReqMsg->ap[i].bssid, nla_data(
3655 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3656 sizeof(tSirMacAddr));
3657 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3658
3659 /* Parse and fetch low RSSI */
3660 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3661 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3662 goto fail;
3663 }
3664 pReqMsg->ap[i].low = nla_get_s32(
3665 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3666 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3667
3668 /* Parse and fetch high RSSI */
3669 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3670 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3671 goto fail;
3672 }
3673 pReqMsg->ap[i].high = nla_get_s32(
3674 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3675 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3676 pReqMsg->ap[i].high);
3677
3678 /* Parse and fetch channel */
3679 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3680 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3681 goto fail;
3682 }
3683 pReqMsg->ap[i].channel = nla_get_u32(
3684 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3685 hddLog(VOS_TRACE_LEVEL_INFO,
3686 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3687 i++;
3688 }
3689 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3690 if (!HAL_STATUS_SUCCESS(status)) {
3691 hddLog(VOS_TRACE_LEVEL_ERROR,
3692 FL("sme_SetBssHotlist failed(err=%d)"), status);
3693 vos_mem_free(pReqMsg);
3694 return -EINVAL;
3695 }
3696
Dino Myclee8843b32014-07-04 14:21:45 +05303697 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303698 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303699 return 0;
3700
3701fail:
3702 vos_mem_free(pReqMsg);
3703 return -EINVAL;
3704}
3705
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303706static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3707 struct wireless_dev *wdev,
3708 const void *data, int dataLen)
3709{
3710 int ret = 0;
3711
3712 vos_ssr_protect(__func__);
3713 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3714 dataLen);
3715 vos_ssr_unprotect(__func__);
3716
3717 return ret;
3718}
3719
3720static int __wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303721 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303722 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303723{
3724 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3725 struct net_device *dev = wdev->netdev;
3726 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3727 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3728 struct nlattr
3729 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3730 struct nlattr
3731 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3732 struct nlattr *apTh;
3733 eHalStatus status;
3734 int i = 0;
3735 int rem;
3736
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303737 ENTER();
3738
Dino Mycle6fb96c12014-06-10 11:52:40 +05303739 status = wlan_hdd_validate_context(pHddCtx);
3740 if (0 != status)
3741 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303742 return -EINVAL;
3743 }
Dino Myclee8843b32014-07-04 14:21:45 +05303744 /* check the EXTScan Capability */
3745 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3746 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3747 {
3748 hddLog(VOS_TRACE_LEVEL_ERROR,
3749 FL("EXTScan not enabled/supported by Firmware"));
3750 return -EINVAL;
3751 }
3752
Dino Mycle6fb96c12014-06-10 11:52:40 +05303753 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3754 data, dataLen,
3755 wlan_hdd_extscan_config_policy)) {
3756 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3757 return -EINVAL;
3758 }
3759
3760 /* Parse and fetch request Id */
3761 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3762 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3763 return -EINVAL;
3764 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303765 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303766 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303767 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303768 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3769 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303770 }
3771
Dino Myclee8843b32014-07-04 14:21:45 +05303772
3773
Dino Mycle6fb96c12014-06-10 11:52:40 +05303774 pReqMsg->requestId = nla_get_u32(
3775 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3776 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3777
3778 /* Parse and fetch RSSI sample size */
3779 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3780 {
3781 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3782 goto fail;
3783 }
3784 pReqMsg->rssiSampleSize = nla_get_u32(
3785 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3786 hddLog(VOS_TRACE_LEVEL_INFO,
3787 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3788
3789 /* Parse and fetch lost AP sample size */
3790 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3791 {
3792 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3793 goto fail;
3794 }
3795 pReqMsg->lostApSampleSize = nla_get_u32(
3796 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3797 hddLog(VOS_TRACE_LEVEL_INFO,
3798 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3799 /* Parse and fetch minimum Breaching */
3800 if (!tb
3801 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3802 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3803 goto fail;
3804 }
3805 pReqMsg->minBreaching = nla_get_u32(
3806 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3807 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3808
3809 /* Parse and fetch number of APs */
3810 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3812 goto fail;
3813 }
3814 pReqMsg->numAp = nla_get_u32(
3815 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3816 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3817
3818 pReqMsg->sessionId = pAdapter->sessionId;
3819 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3820
3821 nla_for_each_nested(apTh,
3822 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3823 if(nla_parse(tb2,
3824 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3825 nla_data(apTh), nla_len(apTh),
3826 NULL)) {
3827 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3828 goto fail;
3829 }
3830
3831 /* Parse and fetch MAC address */
3832 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3833 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3834 goto fail;
3835 }
3836 memcpy(pReqMsg->ap[i].bssid, nla_data(
3837 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3838 sizeof(tSirMacAddr));
3839
3840 /* Parse and fetch low RSSI */
3841 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3842 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3843 goto fail;
3844 }
3845 pReqMsg->ap[i].low = nla_get_s32(
3846 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3847 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3848
3849 /* Parse and fetch high RSSI */
3850 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3851 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3852 goto fail;
3853 }
3854 pReqMsg->ap[i].high = nla_get_s32(
3855 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3856 hddLog(VOS_TRACE_LEVEL_INFO,
3857 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3858
3859 /* Parse and fetch channel */
3860 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3861 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3862 goto fail;
3863 }
3864 pReqMsg->ap[i].channel = nla_get_u32(
3865 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3866 hddLog(VOS_TRACE_LEVEL_INFO,
3867 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3868 i++;
3869 }
3870
3871 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3872 if (!HAL_STATUS_SUCCESS(status)) {
3873 hddLog(VOS_TRACE_LEVEL_ERROR,
3874 FL("sme_SetSignificantChange failed(err=%d)"), status);
3875 vos_mem_free(pReqMsg);
3876 return -EINVAL;
3877 }
Dino Myclee8843b32014-07-04 14:21:45 +05303878 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303879 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303880 return 0;
3881
3882fail:
3883 vos_mem_free(pReqMsg);
3884 return -EINVAL;
3885}
3886
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303887static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3888 struct wireless_dev *wdev,
3889 const void *data, int dataLen)
3890{
3891 int ret = 0;
3892
3893 vos_ssr_protect(__func__);
3894 ret = __wlan_hdd_cfg80211_extscan_set_significant_change(wiphy, wdev, data,
3895 dataLen);
3896 vos_ssr_unprotect(__func__);
3897
3898 return ret;
3899}
3900
3901static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303902 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303903 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303904{
3905 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3906 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3907 tANI_U8 numChannels = 0;
3908 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3909 tANI_U32 requestId;
3910 tWifiBand wifiBand;
3911 eHalStatus status;
3912 struct sk_buff *replySkb;
3913 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303914 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303915
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303916 ENTER();
3917
Dino Mycle6fb96c12014-06-10 11:52:40 +05303918 status = wlan_hdd_validate_context(pHddCtx);
3919 if (0 != status)
3920 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303921 return -EINVAL;
3922 }
Dino Myclee8843b32014-07-04 14:21:45 +05303923
Dino Mycle6fb96c12014-06-10 11:52:40 +05303924 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3925 data, dataLen,
3926 wlan_hdd_extscan_config_policy)) {
3927 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3928 return -EINVAL;
3929 }
3930
3931 /* Parse and fetch request Id */
3932 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3933 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3934 return -EINVAL;
3935 }
3936 requestId = nla_get_u32(
3937 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3938 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3939
3940 /* Parse and fetch wifi band */
3941 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3942 {
3943 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3944 return -EINVAL;
3945 }
3946 wifiBand = nla_get_u32(
3947 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3948 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3949
3950 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3951 wifiBand, ChannelList,
3952 &numChannels);
3953 if (eHAL_STATUS_SUCCESS != status) {
3954 hddLog(VOS_TRACE_LEVEL_ERROR,
3955 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3956 return -EINVAL;
3957 }
3958 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3959 for (i = 0; i < numChannels; i++)
3960 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3961
3962 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3963 sizeof(u32) * numChannels +
3964 NLMSG_HDRLEN);
3965
3966 if (!replySkb) {
3967 hddLog(VOS_TRACE_LEVEL_ERROR,
3968 FL("valid channels: buffer alloc fail"));
3969 return -EINVAL;
3970 }
3971 if (nla_put_u32(replySkb,
3972 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3973 numChannels) ||
3974 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3975 sizeof(u32) * numChannels, ChannelList)) {
3976
3977 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3978 kfree_skb(replySkb);
3979 return -EINVAL;
3980 }
3981
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303982 ret = cfg80211_vendor_cmd_reply(replySkb);
3983
3984 EXIT();
3985 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303986}
3987
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303988static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
3989 struct wireless_dev *wdev,
3990 const void *data, int dataLen)
3991{
3992 int ret = 0;
3993
3994 vos_ssr_protect(__func__);
3995 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
3996 dataLen);
3997 vos_ssr_unprotect(__func__);
3998
3999 return ret;
4000}
4001
4002static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304003 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304004 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304005{
Dino Myclee8843b32014-07-04 14:21:45 +05304006 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304007 struct net_device *dev = wdev->netdev;
4008 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4009 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4010 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4011 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4012 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4013 struct nlattr *buckets;
4014 struct nlattr *channels;
4015 int rem1;
4016 int rem2;
4017 eHalStatus status;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304018 tANI_U32 j = 0, index = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304019
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304020 ENTER();
4021
Dino Mycle6fb96c12014-06-10 11:52:40 +05304022 status = wlan_hdd_validate_context(pHddCtx);
4023 if (0 != status)
4024 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304025 return -EINVAL;
4026 }
Dino Myclee8843b32014-07-04 14:21:45 +05304027 /* check the EXTScan Capability */
4028 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4029 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4030 {
4031 hddLog(VOS_TRACE_LEVEL_ERROR,
4032 FL("EXTScan not enabled/supported by Firmware"));
4033 return -EINVAL;
4034 }
4035
Dino Mycle6fb96c12014-06-10 11:52:40 +05304036 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4037 data, dataLen,
4038 wlan_hdd_extscan_config_policy)) {
4039 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4040 return -EINVAL;
4041 }
4042
4043 /* Parse and fetch request Id */
4044 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4045 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4046 return -EINVAL;
4047 }
4048
Dino Myclee8843b32014-07-04 14:21:45 +05304049 pReqMsg = (tpSirEXTScanStartReqParams)
4050 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304051 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304052 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4053 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304054 }
4055
4056 pReqMsg->requestId = nla_get_u32(
4057 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4058 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4059
4060 pReqMsg->sessionId = pAdapter->sessionId;
4061 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4062
4063 /* Parse and fetch base period */
4064 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
4065 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4066 goto fail;
4067 }
4068 pReqMsg->basePeriod = nla_get_u32(
4069 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
4070 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4071 pReqMsg->basePeriod);
4072
4073 /* Parse and fetch max AP per scan */
4074 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
4075 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4076 goto fail;
4077 }
4078 pReqMsg->maxAPperScan = nla_get_u32(
4079 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
4080 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4081 pReqMsg->maxAPperScan);
4082
4083 /* Parse and fetch report threshold */
4084 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
4085 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4086 goto fail;
4087 }
4088 pReqMsg->reportThreshold = nla_get_u8(
4089 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
4090 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
4091 pReqMsg->reportThreshold);
4092
4093 /* Parse and fetch number of buckets */
4094 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
4095 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4096 goto fail;
4097 }
4098 pReqMsg->numBuckets = nla_get_u8(
4099 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
4100 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4101 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4102 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4103 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4104 }
4105 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4106 pReqMsg->numBuckets);
4107 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4108 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4109 goto fail;
4110 }
4111
4112 nla_for_each_nested(buckets,
4113 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4114 if(nla_parse(bucket,
4115 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4116 nla_data(buckets), nla_len(buckets), NULL)) { //policy
4117 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4118 goto fail;
4119 }
4120
4121 /* Parse and fetch bucket spec */
4122 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4123 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
4124 goto fail;
4125 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304126
4127 pReqMsg->buckets[index].bucket = nla_get_u8(
4128 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4129
4130 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"),
4131 pReqMsg->buckets[index].bucket);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304132
4133 /* Parse and fetch wifi band */
4134 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4135 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4136 goto fail;
4137 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304138 pReqMsg->buckets[index].band = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304139 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4140 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304141 pReqMsg->buckets[index].band);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304142
4143 /* Parse and fetch period */
4144 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4145 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
4146 goto fail;
4147 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304148 pReqMsg->buckets[index].period = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304149 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4150 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304151 pReqMsg->buckets[index].period);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304152
4153 /* Parse and fetch report events */
4154 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4155 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
4156 goto fail;
4157 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304158 pReqMsg->buckets[index].reportEvents = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304159 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4160 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304161 pReqMsg->buckets[index].reportEvents);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304162
4163 /* Parse and fetch number of channels */
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304164 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS])
4165 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304166 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
4167 goto fail;
4168 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304169 pReqMsg->buckets[index].numChannels = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304170 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4171 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304172 pReqMsg->buckets[index].numChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304173
4174 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4175 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
4176 goto fail;
4177 }
4178
4179 j = 0;
4180 nla_for_each_nested(channels,
4181 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4182 if(nla_parse(channel,
4183 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4184 nla_data(channels), nla_len(channels),
4185 NULL)) { //wlan_hdd_extscan_config_policy here
4186 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4187 goto fail;
4188 }
4189
4190 /* Parse and fetch channel */
4191 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4192 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4193 goto fail;
4194 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304195 pReqMsg->buckets[index].channels[j].channel = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304196 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4197 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304198 pReqMsg->buckets[index].channels[j].channel);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304199
4200 /* Parse and fetch dwell time */
4201 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4202 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
4203 goto fail;
4204 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304205 pReqMsg->buckets[index].channels[j].dwellTimeMs = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304206 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4207 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304208 pReqMsg->buckets[index].channels[j].dwellTimeMs);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304209
4210 /* Parse and fetch channel spec passive */
4211 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4212 hddLog(VOS_TRACE_LEVEL_ERROR,
4213 FL("attr channel spec passive failed"));
4214 goto fail;
4215 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304216 pReqMsg->buckets[index].channels[j].passive = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304217 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4218 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304219 pReqMsg->buckets[index].channels[j].passive);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304220 j++;
4221 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304222 index++;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304223 }
4224 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4225 if (!HAL_STATUS_SUCCESS(status)) {
4226 hddLog(VOS_TRACE_LEVEL_ERROR,
4227 FL("sme_EXTScanStart failed(err=%d)"), status);
4228 vos_mem_free(pReqMsg);
4229 return -EINVAL;
4230 }
4231
Dino Myclee8843b32014-07-04 14:21:45 +05304232 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304233 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304234 return 0;
4235
4236fail:
4237 vos_mem_free(pReqMsg);
4238 return -EINVAL;
4239}
4240
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304241static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4242 struct wireless_dev *wdev,
4243 const void *data, int dataLen)
4244{
4245 int ret = 0;
4246
4247 vos_ssr_protect(__func__);
4248 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4249 vos_ssr_unprotect(__func__);
4250
4251 return ret;
4252}
4253
4254static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304255 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304256 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304257{
Dino Myclee8843b32014-07-04 14:21:45 +05304258 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304259 struct net_device *dev = wdev->netdev;
4260 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4261 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4262 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4263 eHalStatus status;
4264
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304265 ENTER();
4266
Dino Mycle6fb96c12014-06-10 11:52:40 +05304267 status = wlan_hdd_validate_context(pHddCtx);
4268 if (0 != status)
4269 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304270 return -EINVAL;
4271 }
Dino Myclee8843b32014-07-04 14:21:45 +05304272 /* check the EXTScan Capability */
4273 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4274 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4275 {
4276 hddLog(VOS_TRACE_LEVEL_ERROR,
4277 FL("EXTScan not enabled/supported by Firmware"));
4278 return -EINVAL;
4279 }
4280
Dino Mycle6fb96c12014-06-10 11:52:40 +05304281 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4282 data, dataLen,
4283 wlan_hdd_extscan_config_policy)) {
4284 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4285 return -EINVAL;
4286 }
4287
4288 /* Parse and fetch request Id */
4289 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4290 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4291 return -EINVAL;
4292 }
4293
Dino Myclee8843b32014-07-04 14:21:45 +05304294 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304295 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304296 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304297
Dino Myclee8843b32014-07-04 14:21:45 +05304298 reqMsg.sessionId = pAdapter->sessionId;
4299 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304300
Dino Myclee8843b32014-07-04 14:21:45 +05304301 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304302 if (!HAL_STATUS_SUCCESS(status)) {
4303 hddLog(VOS_TRACE_LEVEL_ERROR,
4304 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304305 return -EINVAL;
4306 }
4307
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304308 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304309 return 0;
4310}
4311
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304312static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4313 struct wireless_dev *wdev,
4314 const void *data, int dataLen)
4315{
4316 int ret = 0;
4317
4318 vos_ssr_protect(__func__);
4319 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4320 vos_ssr_unprotect(__func__);
4321
4322 return ret;
4323}
4324
4325static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304326 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304327 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304328{
Dino Myclee8843b32014-07-04 14:21:45 +05304329 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304330 struct net_device *dev = wdev->netdev;
4331 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4332 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4333 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4334 eHalStatus status;
4335
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304336 ENTER();
4337
Dino Mycle6fb96c12014-06-10 11:52:40 +05304338 status = wlan_hdd_validate_context(pHddCtx);
4339 if (0 != status)
4340 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304341 return -EINVAL;
4342 }
Dino Myclee8843b32014-07-04 14:21:45 +05304343 /* check the EXTScan Capability */
4344 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4345 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4346 {
4347 hddLog(VOS_TRACE_LEVEL_ERROR,
4348 FL("EXTScan not enabled/supported by Firmware"));
4349 return -EINVAL;
4350 }
4351
Dino Mycle6fb96c12014-06-10 11:52:40 +05304352 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4353 data, dataLen,
4354 wlan_hdd_extscan_config_policy)) {
4355 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4356 return -EINVAL;
4357 }
4358
4359 /* Parse and fetch request Id */
4360 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4361 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4362 return -EINVAL;
4363 }
4364
Dino Myclee8843b32014-07-04 14:21:45 +05304365 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304366 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304367 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304368
Dino Myclee8843b32014-07-04 14:21:45 +05304369 reqMsg.sessionId = pAdapter->sessionId;
4370 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304371
Dino Myclee8843b32014-07-04 14:21:45 +05304372 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304373 if (!HAL_STATUS_SUCCESS(status)) {
4374 hddLog(VOS_TRACE_LEVEL_ERROR,
4375 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304376 return -EINVAL;
4377 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304378 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304379 return 0;
4380}
4381
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304382static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4383 struct wireless_dev *wdev,
4384 const void *data, int dataLen)
4385{
4386 int ret = 0;
4387
4388 vos_ssr_protect(__func__);
4389 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4390 vos_ssr_unprotect(__func__);
4391
4392 return ret;
4393}
4394
4395static int __wlan_hdd_cfg80211_extscan_reset_significant_change(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304396 struct wiphy *wiphy,
4397 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304398 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304399{
Dino Myclee8843b32014-07-04 14:21:45 +05304400 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304401 struct net_device *dev = wdev->netdev;
4402 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4403 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4404 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4405 eHalStatus status;
4406
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304407 ENTER();
4408
Dino Mycle6fb96c12014-06-10 11:52:40 +05304409 status = wlan_hdd_validate_context(pHddCtx);
4410 if (0 != status)
4411 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304412 return -EINVAL;
4413 }
Dino Myclee8843b32014-07-04 14:21:45 +05304414 /* check the EXTScan Capability */
4415 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4416 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4417 {
4418 hddLog(VOS_TRACE_LEVEL_ERROR,
4419 FL("EXTScan not enabled/supported by Firmware"));
4420 return -EINVAL;
4421 }
4422
Dino Mycle6fb96c12014-06-10 11:52:40 +05304423 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4424 data, dataLen,
4425 wlan_hdd_extscan_config_policy)) {
4426 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4427 return -EINVAL;
4428 }
4429
4430 /* Parse and fetch request Id */
4431 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4432 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4433 return -EINVAL;
4434 }
4435
Dino Mycle6fb96c12014-06-10 11:52:40 +05304436
Dino Myclee8843b32014-07-04 14:21:45 +05304437 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304438 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304439 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304440
Dino Myclee8843b32014-07-04 14:21:45 +05304441 reqMsg.sessionId = pAdapter->sessionId;
4442 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304443
Dino Myclee8843b32014-07-04 14:21:45 +05304444 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304445 if (!HAL_STATUS_SUCCESS(status)) {
4446 hddLog(VOS_TRACE_LEVEL_ERROR,
4447 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304448 return -EINVAL;
4449 }
4450
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304451 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304452 return 0;
4453}
4454
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304455static int wlan_hdd_cfg80211_extscan_reset_significant_change(
4456 struct wiphy *wiphy,
4457 struct wireless_dev *wdev,
4458 const void *data, int dataLen)
4459{
4460 int ret = 0;
4461
4462 vos_ssr_protect(__func__);
4463 ret = __wlan_hdd_cfg80211_extscan_reset_significant_change(wiphy,
4464 wdev, data,
4465 dataLen);
4466 vos_ssr_unprotect(__func__);
4467
4468 return ret;
4469}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304470#endif /* WLAN_FEATURE_EXTSCAN */
4471
Atul Mittal115287b2014-07-08 13:26:33 +05304472/*EXT TDLS*/
4473static const struct nla_policy
4474wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4475{
4476 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4477 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4478 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4479 {.type = NLA_S32 },
4480 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4481 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4482
4483};
4484
4485static const struct nla_policy
4486wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4487{
4488 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4489
4490};
4491
4492static const struct nla_policy
4493wlan_hdd_tdls_config_state_change_policy[
4494 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4495{
4496 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4497 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4498 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304499 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4500 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4501 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304502
4503};
4504
4505static const struct nla_policy
4506wlan_hdd_tdls_config_get_status_policy[
4507 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4508{
4509 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4510 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4511 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304512 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4513 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4514 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304515
4516};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304517
4518static const struct nla_policy
4519wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4520{
4521 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
4522};
4523
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304524static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304525 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304526 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304527 int data_len)
4528{
4529
4530 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4531 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
4532
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304533 ENTER();
4534
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304535 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304536 return -EINVAL;
4537 }
4538 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
4539 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN disabled in ini"));
4540 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05304541 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304542 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
4543 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN not supported by FW"));
4544 return -ENOTSUPP;
4545 }
4546
4547 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
4548 data, data_len, wlan_hdd_mac_config)) {
4549 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4550 return -EINVAL;
4551 }
4552
4553 /* Parse and fetch mac address */
4554 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
4555 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4556 return -EINVAL;
4557 }
4558
4559 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
4560 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4561 VOS_MAC_ADDR_LAST_3_BYTES);
4562
Siddharth Bhal76972212014-10-15 16:22:51 +05304563 pHddCtx->spoofMacAddr.isEnabled = TRUE;
4564
4565 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304566 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4567 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05304568 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
4569 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
4570 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
4571 {
4572 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
4573 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
4574 VOS_MAC_ADDRESS_LEN);
4575 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304576 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304577
Siddharth Bhal76972212014-10-15 16:22:51 +05304578 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
4579 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304580 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
4581 }
4582
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304583 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304584 return 0;
4585}
4586
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304587static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
4588 struct wireless_dev *wdev,
4589 const void *data,
4590 int data_len)
4591{
4592 int ret = 0;
4593
4594 vos_ssr_protect(__func__);
4595 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
4596 vos_ssr_unprotect(__func__);
4597
4598 return ret;
4599}
4600
4601static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304602 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304603 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304604 int data_len)
4605{
4606 u8 peer[6] = {0};
4607 struct net_device *dev = wdev->netdev;
4608 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4609 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4610 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
4611 eHalStatus ret;
4612 tANI_S32 state;
4613 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304614 tANI_S32 global_operating_class = 0;
4615 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304616 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304617 int retVal;
4618
4619 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304620
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304621 if (!pAdapter) {
4622 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4623 return -EINVAL;
4624 }
4625
Atul Mittal115287b2014-07-08 13:26:33 +05304626 ret = wlan_hdd_validate_context(pHddCtx);
4627 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304628 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304629 return -EINVAL;
4630 }
4631 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304632 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304633 return -ENOTSUPP;
4634 }
4635 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4636 data, data_len,
4637 wlan_hdd_tdls_config_get_status_policy)) {
4638 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4639 return -EINVAL;
4640 }
4641
4642 /* Parse and fetch mac address */
4643 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4644 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4645 return -EINVAL;
4646 }
4647
4648 memcpy(peer, nla_data(
4649 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4650 sizeof(peer));
4651 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4652
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05304653 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05304654
Atul Mittal115287b2014-07-08 13:26:33 +05304655 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304656 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05304657 NLMSG_HDRLEN);
4658
4659 if (!skb) {
4660 hddLog(VOS_TRACE_LEVEL_ERROR,
4661 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4662 return -EINVAL;
4663 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304664 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 +05304665 reason,
4666 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304667 global_operating_class,
4668 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05304669 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304670 if (nla_put_s32(skb,
4671 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
4672 state) ||
4673 nla_put_s32(skb,
4674 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
4675 reason) ||
4676 nla_put_s32(skb,
4677 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
4678 global_operating_class) ||
4679 nla_put_s32(skb,
4680 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
4681 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304682
4683 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4684 goto nla_put_failure;
4685 }
4686
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304687 retVal = cfg80211_vendor_cmd_reply(skb);
4688 EXIT();
4689 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05304690
4691nla_put_failure:
4692 kfree_skb(skb);
4693 return -EINVAL;
4694}
4695
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304696static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
4697 struct wireless_dev *wdev,
4698 const void *data,
4699 int data_len)
4700{
4701 int ret = 0;
4702
4703 vos_ssr_protect(__func__);
4704 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
4705 vos_ssr_unprotect(__func__);
4706
4707 return ret;
4708}
4709
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05304710static int wlan_hdd_cfg80211_exttdls_callback(
4711#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
4712 const tANI_U8* mac,
4713#else
4714 tANI_U8* mac,
4715#endif
Atul Mittal115287b2014-07-08 13:26:33 +05304716 tANI_S32 state,
4717 tANI_S32 reason,
4718 void *ctx)
4719{
4720 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05304721 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304722 tANI_S32 global_operating_class = 0;
4723 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304724 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05304725
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304726 ENTER();
4727
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304728 if (!pAdapter) {
4729 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4730 return -EINVAL;
4731 }
4732
4733 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05304734 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304735 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304736 return -EINVAL;
4737 }
4738
4739 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304740 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304741 return -ENOTSUPP;
4742 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304743 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
4744#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4745 NULL,
4746#endif
Atul Mittal115287b2014-07-08 13:26:33 +05304747 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4748 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4749 GFP_KERNEL);
4750
4751 if (!skb) {
4752 hddLog(VOS_TRACE_LEVEL_ERROR,
4753 FL("cfg80211_vendor_event_alloc failed"));
4754 return -EINVAL;
4755 }
4756 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304757 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
4758 reason,
4759 state,
4760 global_operating_class,
4761 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05304762 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4763 MAC_ADDR_ARRAY(mac));
4764
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304765 if (nla_put(skb,
4766 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4767 VOS_MAC_ADDR_SIZE, mac) ||
4768 nla_put_s32(skb,
4769 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
4770 state) ||
4771 nla_put_s32(skb,
4772 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
4773 reason) ||
4774 nla_put_s32(skb,
4775 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
4776 channel) ||
4777 nla_put_s32(skb,
4778 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
4779 global_operating_class)
4780 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05304781 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4782 goto nla_put_failure;
4783 }
4784
4785 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304786 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05304787 return (0);
4788
4789nla_put_failure:
4790 kfree_skb(skb);
4791 return -EINVAL;
4792}
4793
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304794static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304795 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304796 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304797 int data_len)
4798{
4799 u8 peer[6] = {0};
4800 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304801 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4802 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4803 eHalStatus status;
4804 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304805 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304806 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304807
4808 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304809
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304810 if (!dev) {
4811 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4812 return -EINVAL;
4813 }
4814
4815 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4816 if (!pAdapter) {
4817 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4818 return -EINVAL;
4819 }
4820
Atul Mittal115287b2014-07-08 13:26:33 +05304821 status = wlan_hdd_validate_context(pHddCtx);
4822 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304823 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304824 return -EINVAL;
4825 }
4826 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304827 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304828 return -ENOTSUPP;
4829 }
4830 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4831 data, data_len,
4832 wlan_hdd_tdls_config_enable_policy)) {
4833 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4834 return -EINVAL;
4835 }
4836
4837 /* Parse and fetch mac address */
4838 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4839 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4840 return -EINVAL;
4841 }
4842
4843 memcpy(peer, nla_data(
4844 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4845 sizeof(peer));
4846 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4847
4848 /* Parse and fetch channel */
4849 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4850 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4851 return -EINVAL;
4852 }
4853 pReqMsg.channel = nla_get_s32(
4854 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4855 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4856
4857 /* Parse and fetch global operating class */
4858 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4859 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4860 return -EINVAL;
4861 }
4862 pReqMsg.global_operating_class = nla_get_s32(
4863 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4864 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4865 pReqMsg.global_operating_class);
4866
4867 /* Parse and fetch latency ms */
4868 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4869 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4870 return -EINVAL;
4871 }
4872 pReqMsg.max_latency_ms = nla_get_s32(
4873 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4874 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4875 pReqMsg.max_latency_ms);
4876
4877 /* Parse and fetch required bandwidth kbps */
4878 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4879 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4880 return -EINVAL;
4881 }
4882
4883 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4884 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4885 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4886 pReqMsg.min_bandwidth_kbps);
4887
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304888 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05304889 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05304890 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304891 wlan_hdd_cfg80211_exttdls_callback);
4892
4893 EXIT();
4894 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304895}
4896
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304897static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4898 struct wireless_dev *wdev,
4899 const void *data,
4900 int data_len)
4901{
4902 int ret = 0;
4903
4904 vos_ssr_protect(__func__);
4905 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
4906 vos_ssr_unprotect(__func__);
4907
4908 return ret;
4909}
4910
4911static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304912 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304913 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304914 int data_len)
4915{
4916 u8 peer[6] = {0};
4917 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304918 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4919 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4920 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304921 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304922 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304923
4924 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304925
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304926 if (!dev) {
4927 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4928 return -EINVAL;
4929 }
4930
4931 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4932 if (!pAdapter) {
4933 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
4934 return -EINVAL;
4935 }
4936
Atul Mittal115287b2014-07-08 13:26:33 +05304937 status = wlan_hdd_validate_context(pHddCtx);
4938 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304939 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304940 return -EINVAL;
4941 }
4942 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304943 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304944 return -ENOTSUPP;
4945 }
4946 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4947 data, data_len,
4948 wlan_hdd_tdls_config_disable_policy)) {
4949 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4950 return -EINVAL;
4951 }
4952 /* Parse and fetch mac address */
4953 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4954 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4955 return -EINVAL;
4956 }
4957
4958 memcpy(peer, nla_data(
4959 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4960 sizeof(peer));
4961 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4962
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304963 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
4964
4965 EXIT();
4966 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304967}
4968
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304969static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4970 struct wireless_dev *wdev,
4971 const void *data,
4972 int data_len)
4973{
4974 int ret = 0;
4975
4976 vos_ssr_protect(__func__);
4977 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
4978 vos_ssr_unprotect(__func__);
4979
4980 return ret;
4981}
4982
Dasari Srinivas7875a302014-09-26 17:50:57 +05304983static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304984__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05304985 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304986 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05304987{
4988 struct net_device *dev = wdev->netdev;
4989 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4990 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4991 struct sk_buff *skb = NULL;
4992 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304993 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05304994
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304995 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304996
4997 ret = wlan_hdd_validate_context(pHddCtx);
4998 if (0 != ret)
4999 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305000 return ret;
5001 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305002 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5003 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5004 fset |= WIFI_FEATURE_INFRA;
5005 }
5006
5007 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5008 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5009 fset |= WIFI_FEATURE_INFRA_5G;
5010 }
5011
5012#ifdef WLAN_FEATURE_P2P
5013 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5014 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5015 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5016 fset |= WIFI_FEATURE_P2P;
5017 }
5018#endif
5019
5020 /* Soft-AP is supported currently by default */
5021 fset |= WIFI_FEATURE_SOFT_AP;
5022
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305023 /* HOTSPOT is a supplicant feature, enable it by default */
5024 fset |= WIFI_FEATURE_HOTSPOT;
5025
Dasari Srinivas7875a302014-09-26 17:50:57 +05305026#ifdef WLAN_FEATURE_EXTSCAN
5027 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
5028 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
5029 hddLog(LOG1, FL("EXTScan is supported by firmware"));
5030 fset |= WIFI_FEATURE_EXTSCAN;
5031 }
5032#endif
5033
Dasari Srinivas7875a302014-09-26 17:50:57 +05305034 if (sme_IsFeatureSupportedByFW(NAN)) {
5035 hddLog(LOG1, FL("NAN is supported by firmware"));
5036 fset |= WIFI_FEATURE_NAN;
5037 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305038
5039 /* D2D RTT is not supported currently by default */
5040 if (sme_IsFeatureSupportedByFW(RTT)) {
5041 hddLog(LOG1, FL("RTT is supported by firmware"));
5042 fset |= WIFI_FEATURE_D2AP_RTT;
5043 }
5044
5045#ifdef FEATURE_WLAN_BATCH_SCAN
5046 if (fset & WIFI_FEATURE_EXTSCAN) {
5047 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5048 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5049 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5050 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5051 fset |= WIFI_FEATURE_BATCH_SCAN;
5052 }
5053#endif
5054
5055#ifdef FEATURE_WLAN_SCAN_PNO
5056 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5057 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5058 hddLog(LOG1, FL("PNO is supported by firmware"));
5059 fset |= WIFI_FEATURE_PNO;
5060 }
5061#endif
5062
5063 /* STA+STA is supported currently by default */
5064 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5065
5066#ifdef FEATURE_WLAN_TDLS
5067 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5068 sme_IsFeatureSupportedByFW(TDLS)) {
5069 hddLog(LOG1, FL("TDLS is supported by firmware"));
5070 fset |= WIFI_FEATURE_TDLS;
5071 }
5072
5073 /* TDLS_OFFCHANNEL is not supported currently by default */
5074#endif
5075
5076#ifdef WLAN_AP_STA_CONCURRENCY
5077 /* AP+STA concurrency is supported currently by default */
5078 fset |= WIFI_FEATURE_AP_STA;
5079#endif
5080
5081 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5082 NLMSG_HDRLEN);
5083
5084 if (!skb) {
5085 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5086 return -EINVAL;
5087 }
5088 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5089
5090 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5091 hddLog(LOGE, FL("nla put fail"));
5092 goto nla_put_failure;
5093 }
5094
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305095 ret = cfg80211_vendor_cmd_reply(skb);
5096 EXIT();
5097 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305098
5099nla_put_failure:
5100 kfree_skb(skb);
5101 return -EINVAL;
5102}
5103
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305104static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305105wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5106 struct wireless_dev *wdev,
5107 const void *data, int data_len)
5108{
5109 int ret = 0;
5110
5111 vos_ssr_protect(__func__);
5112 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5113 vos_ssr_unprotect(__func__);
5114
5115 return ret;
5116}
5117
5118static int
5119__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305120 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305121 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305122{
5123 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5124 uint8_t i, feature_sets, max_feature_sets;
5125 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5126 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305127 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5128 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305129
5130 ENTER();
5131
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305132 ret = wlan_hdd_validate_context(pHddCtx);
5133 if (0 != ret)
5134 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305135 return ret;
5136 }
5137
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305138 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5139 data, data_len, NULL)) {
5140 hddLog(LOGE, FL("Invalid ATTR"));
5141 return -EINVAL;
5142 }
5143
5144 /* Parse and fetch max feature set */
5145 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5146 hddLog(LOGE, FL("Attr max feature set size failed"));
5147 return -EINVAL;
5148 }
5149 max_feature_sets = nla_get_u32(
5150 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5151 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5152
5153 /* Fill feature combination matrix */
5154 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305155 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5156 WIFI_FEATURE_P2P;
5157
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305158 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5159 WIFI_FEATURE_SOFT_AP;
5160
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305161 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5162 WIFI_FEATURE_SOFT_AP;
5163
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305164 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5165 WIFI_FEATURE_SOFT_AP |
5166 WIFI_FEATURE_P2P;
5167
5168 /* Add more feature combinations here */
5169
5170 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5171 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5172 hddLog(LOG1, "Feature set matrix");
5173 for (i = 0; i < feature_sets; i++)
5174 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5175
5176 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5177 sizeof(u32) * feature_sets +
5178 NLMSG_HDRLEN);
5179
5180 if (reply_skb) {
5181 if (nla_put_u32(reply_skb,
5182 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5183 feature_sets) ||
5184 nla_put(reply_skb,
5185 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5186 sizeof(u32) * feature_sets, feature_set_matrix)) {
5187 hddLog(LOGE, FL("nla put fail"));
5188 kfree_skb(reply_skb);
5189 return -EINVAL;
5190 }
5191
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305192 ret = cfg80211_vendor_cmd_reply(reply_skb);
5193 EXIT();
5194 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305195 }
5196 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5197 return -ENOMEM;
5198
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305199}
5200
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305201static int
5202wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5203 struct wireless_dev *wdev,
5204 const void *data, int data_len)
5205{
5206 int ret = 0;
5207
5208 vos_ssr_protect(__func__);
5209 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5210 data_len);
5211 vos_ssr_unprotect(__func__);
5212
5213 return ret;
5214}
5215
Agarwal Ashish738843c2014-09-25 12:27:56 +05305216static const struct nla_policy
5217wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5218 +1] =
5219{
5220 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5221};
5222
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305223static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305224 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305225 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305226 int data_len)
5227{
5228 struct net_device *dev = wdev->netdev;
5229 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5230 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5231 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5232 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5233 eHalStatus status;
5234 u32 dfsFlag = 0;
5235
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305236 ENTER();
5237
Agarwal Ashish738843c2014-09-25 12:27:56 +05305238 status = wlan_hdd_validate_context(pHddCtx);
5239 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305240 return -EINVAL;
5241 }
5242 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5243 data, data_len,
5244 wlan_hdd_set_no_dfs_flag_config_policy)) {
5245 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5246 return -EINVAL;
5247 }
5248
5249 /* Parse and fetch required bandwidth kbps */
5250 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5251 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5252 return -EINVAL;
5253 }
5254
5255 dfsFlag = nla_get_u32(
5256 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5257 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5258 dfsFlag);
5259
5260 pHddCtx->disable_dfs_flag = dfsFlag;
5261
5262 sme_disable_dfs_channel(hHal, dfsFlag);
5263 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305264
5265 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305266 return 0;
5267}
Atul Mittal115287b2014-07-08 13:26:33 +05305268
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305269static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
5270 struct wireless_dev *wdev,
5271 const void *data,
5272 int data_len)
5273{
5274 int ret = 0;
5275
5276 vos_ssr_protect(__func__);
5277 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
5278 vos_ssr_unprotect(__func__);
5279
5280 return ret;
5281
5282}
5283
Mukul Sharma2a271632014-10-13 14:59:01 +05305284const struct
5285nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
5286{
5287 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
5288 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
5289};
5290
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305291static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05305292 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05305293{
5294
5295 u8 bssid[6] = {0};
5296 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5297 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5298 eHalStatus status = eHAL_STATUS_SUCCESS;
5299 v_U32_t isFwrRoamEnabled = FALSE;
5300 int ret;
5301
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305302 ENTER();
5303
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305304 ret = wlan_hdd_validate_context(pHddCtx);
5305 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305306 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05305307 }
5308
5309 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
5310 data, data_len,
5311 qca_wlan_vendor_attr);
5312 if (ret){
5313 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5314 return -EINVAL;
5315 }
5316
5317 /* Parse and fetch Enable flag */
5318 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
5319 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
5320 return -EINVAL;
5321 }
5322
5323 isFwrRoamEnabled = nla_get_u32(
5324 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5325
5326 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5327
5328 /* Parse and fetch bssid */
5329 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5330 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5331 return -EINVAL;
5332 }
5333
5334 memcpy(bssid, nla_data(
5335 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
5336 sizeof(bssid));
5337 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
5338
5339 //Update roaming
5340 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305341 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05305342 return status;
5343}
5344
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305345static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
5346 struct wireless_dev *wdev, const void *data, int data_len)
5347{
5348 int ret = 0;
5349
5350 vos_ssr_protect(__func__);
5351 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
5352 vos_ssr_unprotect(__func__);
5353
5354 return ret;
5355}
5356
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305357/**
5358 * __wlan_hdd_cfg80211_setband() - set band
5359 * @wiphy: Pointer to wireless phy
5360 * @wdev: Pointer to wireless device
5361 * @data: Pointer to data
5362 * @data_len: Data length
5363 *
5364 * Return: 0 on success, negative errno on failure
5365 */
5366static int
5367__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
5368 struct wireless_dev *wdev,
5369 const void *data,
5370 int data_len)
5371{
5372 struct net_device *dev = wdev->netdev;
5373 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5374 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5375 int ret;
5376 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
5377 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
5378
5379 ENTER();
5380
5381 ret = wlan_hdd_validate_context(hdd_ctx);
5382 if (0 != ret) {
5383 hddLog(LOGE, FL("HDD context is not valid"));
5384 return ret;
5385 }
5386
5387 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
5388 policy)) {
5389 hddLog(LOGE, FL("Invalid ATTR"));
5390 return -EINVAL;
5391 }
5392
5393 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
5394 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
5395 return -EINVAL;
5396 }
5397
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05305398 hdd_ctx->isSetBandByNL = TRUE;
5399 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305400 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05305401 hdd_ctx->isSetBandByNL = FALSE;
5402
5403 EXIT();
5404 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305405}
5406
5407/**
5408 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
5409 * @wiphy: wiphy structure pointer
5410 * @wdev: Wireless device structure pointer
5411 * @data: Pointer to the data received
5412 * @data_len: Length of @data
5413 *
5414 * Return: 0 on success; errno on failure
5415 */
5416static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
5417 struct wireless_dev *wdev,
5418 const void *data,
5419 int data_len)
5420{
5421 int ret = 0;
5422
5423 vos_ssr_protect(__func__);
5424 ret = __wlan_hdd_cfg80211_setband(wiphy,
5425 wdev, data, data_len);
5426 vos_ssr_unprotect(__func__);
5427
5428 return ret;
5429}
5430
Sunil Duttc69bccb2014-05-26 21:30:20 +05305431const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
5432{
Mukul Sharma2a271632014-10-13 14:59:01 +05305433 {
5434 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5435 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
5436 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5437 WIPHY_VENDOR_CMD_NEED_NETDEV |
5438 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305439 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05305440 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05305441
5442 {
5443 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5444 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
5445 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5446 WIPHY_VENDOR_CMD_NEED_NETDEV |
5447 WIPHY_VENDOR_CMD_NEED_RUNNING,
5448 .doit = wlan_hdd_cfg80211_nan_request
5449 },
5450
Sunil Duttc69bccb2014-05-26 21:30:20 +05305451#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5452 {
5453 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5454 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
5455 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5456 WIPHY_VENDOR_CMD_NEED_NETDEV |
5457 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305458 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05305459 },
5460
5461 {
5462 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5463 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
5464 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5465 WIPHY_VENDOR_CMD_NEED_NETDEV |
5466 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305467 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05305468 },
5469
5470 {
5471 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5472 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
5473 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5474 WIPHY_VENDOR_CMD_NEED_NETDEV |
5475 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305476 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05305477 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305478#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305479#ifdef WLAN_FEATURE_EXTSCAN
5480 {
5481 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5482 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
5483 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5484 WIPHY_VENDOR_CMD_NEED_NETDEV |
5485 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305486 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05305487 },
5488 {
5489 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5490 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
5491 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5492 WIPHY_VENDOR_CMD_NEED_NETDEV |
5493 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305494 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05305495 },
5496 {
5497 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5498 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
5499 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5500 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305501 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05305502 },
5503 {
5504 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5505 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
5506 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5507 WIPHY_VENDOR_CMD_NEED_NETDEV |
5508 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305509 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05305510 },
5511 {
5512 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5513 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
5514 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5515 WIPHY_VENDOR_CMD_NEED_NETDEV |
5516 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305517 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
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_SET_BSSID_HOTLIST,
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_set_bssid_hotlist
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_RESET_BSSID_HOTLIST,
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_reset_bssid_hotlist
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_SIGNIFICANT_CHANGE,
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_significant_change
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_SIGNIFICANT_CHANGE,
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_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305550 },
5551#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305552/*EXT TDLS*/
5553 {
5554 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5555 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
5556 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5557 WIPHY_VENDOR_CMD_NEED_NETDEV |
5558 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305559 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05305560 },
5561 {
5562 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5563 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
5564 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5565 WIPHY_VENDOR_CMD_NEED_NETDEV |
5566 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305567 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05305568 },
5569 {
5570 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5571 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
5572 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5573 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305574 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05305575 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05305576 {
5577 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5578 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
5579 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5580 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305581 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05305582 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05305583 {
5584 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5585 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
5586 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5587 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305588 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05305589 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305590 {
5591 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5592 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
5593 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5594 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305595 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305596 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305597 {
5598 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5599 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
5600 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5601 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305602 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305603 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305604 {
5605 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5606 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
5607 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5608 WIPHY_VENDOR_CMD_NEED_NETDEV |
5609 WIPHY_VENDOR_CMD_NEED_RUNNING,
5610 .doit = wlan_hdd_cfg80211_setband
5611 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05305612};
5613
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005614/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05305615static const
5616struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005617{
5618#ifdef FEATURE_WLAN_CH_AVOID
5619 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05305620 .vendor_id = QCA_NL80211_VENDOR_ID,
5621 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005622 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305623#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
5624#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5625 {
5626 /* Index = 1*/
5627 .vendor_id = QCA_NL80211_VENDOR_ID,
5628 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
5629 },
5630 {
5631 /* Index = 2*/
5632 .vendor_id = QCA_NL80211_VENDOR_ID,
5633 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
5634 },
5635 {
5636 /* Index = 3*/
5637 .vendor_id = QCA_NL80211_VENDOR_ID,
5638 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
5639 },
5640 {
5641 /* Index = 4*/
5642 .vendor_id = QCA_NL80211_VENDOR_ID,
5643 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
5644 },
5645 {
5646 /* Index = 5*/
5647 .vendor_id = QCA_NL80211_VENDOR_ID,
5648 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
5649 },
5650 {
5651 /* Index = 6*/
5652 .vendor_id = QCA_NL80211_VENDOR_ID,
5653 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
5654 },
5655#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305656#ifdef WLAN_FEATURE_EXTSCAN
5657 {
5658 .vendor_id = QCA_NL80211_VENDOR_ID,
5659 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
5660 },
5661 {
5662 .vendor_id = QCA_NL80211_VENDOR_ID,
5663 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
5664 },
5665 {
5666 .vendor_id = QCA_NL80211_VENDOR_ID,
5667 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
5668 },
5669 {
5670 .vendor_id = QCA_NL80211_VENDOR_ID,
5671 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
5672 },
5673 {
5674 .vendor_id = QCA_NL80211_VENDOR_ID,
5675 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
5676 },
5677 {
5678 .vendor_id = QCA_NL80211_VENDOR_ID,
5679 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
5680 },
5681 {
5682 .vendor_id = QCA_NL80211_VENDOR_ID,
5683 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
5684 },
5685 {
5686 .vendor_id = QCA_NL80211_VENDOR_ID,
5687 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
5688 },
5689 {
5690 .vendor_id = QCA_NL80211_VENDOR_ID,
5691 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
5692 },
5693 {
5694 .vendor_id = QCA_NL80211_VENDOR_ID,
5695 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
5696 },
5697 {
5698 .vendor_id = QCA_NL80211_VENDOR_ID,
5699 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
5700 },
5701 {
5702 .vendor_id = QCA_NL80211_VENDOR_ID,
5703 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
5704 },
5705 {
5706 .vendor_id = QCA_NL80211_VENDOR_ID,
5707 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
5708 },
5709#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305710/*EXT TDLS*/
5711 {
5712 .vendor_id = QCA_NL80211_VENDOR_ID,
5713 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
5714 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05305715
5716 {
5717 .vendor_id = QCA_NL80211_VENDOR_ID,
5718 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
5719 },
5720
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005721};
5722
Jeff Johnson295189b2012-06-20 16:38:30 -07005723/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305724 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305725 * This function is called by hdd_wlan_startup()
5726 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305727 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07005728 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305729struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07005730{
5731 struct wiphy *wiphy;
5732 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305733 /*
5734 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07005735 */
5736 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
5737
5738 if (!wiphy)
5739 {
5740 /* Print error and jump into err label and free the memory */
5741 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
5742 return NULL;
5743 }
5744
Sunil Duttc69bccb2014-05-26 21:30:20 +05305745
Jeff Johnson295189b2012-06-20 16:38:30 -07005746 return wiphy;
5747}
5748
5749/*
5750 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305751 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07005752 * private ioctl to change the band value
5753 */
5754int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
5755{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305756 int i, j;
5757 eNVChannelEnabledType channelEnabledState;
5758
Jeff Johnsone7245742012-09-05 17:12:55 -07005759 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305760
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305761 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005762 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305763
5764 if (NULL == wiphy->bands[i])
5765 {
5766 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5767 __func__, i);
5768 continue;
5769 }
5770
5771 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5772 {
5773 struct ieee80211_supported_band *band = wiphy->bands[i];
5774
5775 channelEnabledState = vos_nv_getChannelEnabledState(
5776 band->channels[j].hw_value);
5777
5778 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
5779 {
Abhishek Singh678227a2014-11-04 10:52:38 +05305780 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305781 continue;
5782 }
5783 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
5784 {
5785 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5786 continue;
5787 }
5788
5789 if (NV_CHANNEL_DISABLE == channelEnabledState ||
5790 NV_CHANNEL_INVALID == channelEnabledState)
5791 {
5792 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5793 }
5794 else if (NV_CHANNEL_DFS == channelEnabledState)
5795 {
5796 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5797 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
5798 }
5799 else
5800 {
5801 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
5802 |IEEE80211_CHAN_RADAR);
5803 }
5804 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005805 }
5806 return 0;
5807}
5808/*
5809 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305810 * This function is called by hdd_wlan_startup()
5811 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07005812 * This function is used to initialize and register wiphy structure.
5813 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305814int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005815 struct wiphy *wiphy,
5816 hdd_config_t *pCfg
5817 )
5818{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305819 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305820 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5821
Jeff Johnsone7245742012-09-05 17:12:55 -07005822 ENTER();
5823
Jeff Johnson295189b2012-06-20 16:38:30 -07005824 /* Now bind the underlying wlan device with wiphy */
5825 set_wiphy_dev(wiphy, dev);
5826
5827 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005828
Kiet Lam6c583332013-10-14 05:37:09 +05305829#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07005830 /* the flag for the other case would be initialzed in
5831 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07005832 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05305833#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005834
Amar Singhalfddc28c2013-09-05 13:03:40 -07005835 /* This will disable updating of NL channels from passive to
5836 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05305837#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
5838 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
5839#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07005840 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05305841#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07005842
Amar Singhala49cbc52013-10-08 18:37:44 -07005843
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005844#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07005845 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
5846 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
5847 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07005848 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05305849#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
5850 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
5851#else
5852 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
5853#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005854#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005855
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005856#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005857 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08005858#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005859 || pCfg->isFastRoamIniFeatureEnabled
5860#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005861#ifdef FEATURE_WLAN_ESE
5862 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005863#endif
5864 )
5865 {
5866 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5867 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08005868#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005869#ifdef FEATURE_WLAN_TDLS
5870 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
5871 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
5872#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305873#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05305874 if (pCfg->configPNOScanSupport)
5875 {
5876 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5877 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
5878 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
5879 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
5880 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305881#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005882
Abhishek Singh10d85972015-04-17 10:27:23 +05305883#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5884 wiphy->features |= NL80211_FEATURE_HT_IBSS;
5885#endif
5886
Amar Singhalfddc28c2013-09-05 13:03:40 -07005887#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005888 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
5889 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07005890 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005891 driver need to determine what to do with both
5892 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07005893
5894 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07005895#else
5896 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005897#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005898
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305899 wiphy->max_scan_ssids = MAX_SCAN_SSID;
5900
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05305901 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07005902
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305903 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
5904
Jeff Johnson295189b2012-06-20 16:38:30 -07005905 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05305906 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
5907 | BIT(NL80211_IFTYPE_ADHOC)
5908 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5909 | BIT(NL80211_IFTYPE_P2P_GO)
5910 | BIT(NL80211_IFTYPE_AP);
5911
5912 if (VOS_MONITOR_MODE == hdd_get_conparam())
5913 {
5914 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
5915 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005916
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305917 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005918 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305919#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5920 if( pCfg->enableMCC )
5921 {
5922 /* Currently, supports up to two channels */
5923 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005924
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305925 if( !pCfg->allowMCCGODiffBI )
5926 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005927
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305928 }
5929 wiphy->iface_combinations = &wlan_hdd_iface_combination;
5930 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005931#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305932 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005933
Jeff Johnson295189b2012-06-20 16:38:30 -07005934 /* Before registering we need to update the ht capabilitied based
5935 * on ini values*/
5936 if( !pCfg->ShortGI20MhzEnable )
5937 {
5938 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5939 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5940 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5941 }
5942
5943 if( !pCfg->ShortGI40MhzEnable )
5944 {
5945 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
5946 }
5947
5948 if( !pCfg->nChannelBondingMode5GHz )
5949 {
5950 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5951 }
5952
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305953 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305954 if (true == hdd_is_5g_supported(pHddCtx))
5955 {
5956 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
5957 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305958
5959 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
5960 {
5961
5962 if (NULL == wiphy->bands[i])
5963 {
5964 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5965 __func__, i);
5966 continue;
5967 }
5968
5969 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5970 {
5971 struct ieee80211_supported_band *band = wiphy->bands[i];
5972
5973 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
5974 {
5975 // Enable social channels for P2P
5976 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
5977 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5978 else
5979 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5980 continue;
5981 }
5982 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
5983 {
5984 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5985 continue;
5986 }
5987 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005988 }
5989 /*Initialise the supported cipher suite details*/
5990 wiphy->cipher_suites = hdd_cipher_suites;
5991 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
5992
5993 /*signal strength in mBm (100*dBm) */
5994 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5995
5996#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05305997 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07005998#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07005999
Sunil Duttc69bccb2014-05-26 21:30:20 +05306000 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
6001 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006002 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
6003 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
6004
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306005 EXIT();
6006 return 0;
6007}
6008
6009/* In this function we are registering wiphy. */
6010int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
6011{
6012 ENTER();
6013 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006014 if (0 > wiphy_register(wiphy))
6015 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306016 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07006017 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
6018 return -EIO;
6019 }
6020
6021 EXIT();
6022 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306023}
Jeff Johnson295189b2012-06-20 16:38:30 -07006024
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306025/* In this function we are updating channel list when,
6026 regulatory domain is FCC and country code is US.
6027 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
6028 As per FCC smart phone is not a indoor device.
6029 GO should not opeate on indoor channels */
6030void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
6031{
6032 int j;
6033 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6034 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
6035 //Default counrtycode from NV at the time of wiphy initialization.
6036 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
6037 &defaultCountryCode[0]))
6038 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006039 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306040 }
6041 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
6042 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306043 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
6044 {
6045 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
6046 return;
6047 }
6048 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
6049 {
6050 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
6051 // Mark UNII -1 band channel as passive
6052 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
6053 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
6054 }
6055 }
6056}
6057
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306058/* This function registers for all frame which supplicant is interested in */
6059void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006060{
Jeff Johnson295189b2012-06-20 16:38:30 -07006061 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6062 /* Register for all P2P action, public action etc frames */
6063 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6064
Jeff Johnsone7245742012-09-05 17:12:55 -07006065 ENTER();
6066
Jeff Johnson295189b2012-06-20 16:38:30 -07006067 /* Right now we are registering these frame when driver is getting
6068 initialized. Once we will move to 2.6.37 kernel, in which we have
6069 frame register ops, we will move this code as a part of that */
6070 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306071 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006072 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6073
6074 /* GAS Initial Response */
6075 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6076 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306077
Jeff Johnson295189b2012-06-20 16:38:30 -07006078 /* GAS Comeback Request */
6079 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6080 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6081
6082 /* GAS Comeback Response */
6083 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6084 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6085
6086 /* P2P Public Action */
6087 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306088 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006089 P2P_PUBLIC_ACTION_FRAME_SIZE );
6090
6091 /* P2P Action */
6092 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6093 (v_U8_t*)P2P_ACTION_FRAME,
6094 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07006095
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05306096 /* WNM BSS Transition Request frame */
6097 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6098 (v_U8_t*)WNM_BSS_ACTION_FRAME,
6099 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006100
6101 /* WNM-Notification */
6102 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6103 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6104 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006105}
6106
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306107void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006108{
Jeff Johnson295189b2012-06-20 16:38:30 -07006109 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6110 /* Register for all P2P action, public action etc frames */
6111 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6112
Jeff Johnsone7245742012-09-05 17:12:55 -07006113 ENTER();
6114
Jeff Johnson295189b2012-06-20 16:38:30 -07006115 /* Right now we are registering these frame when driver is getting
6116 initialized. Once we will move to 2.6.37 kernel, in which we have
6117 frame register ops, we will move this code as a part of that */
6118 /* GAS Initial Request */
6119
6120 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6121 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6122
6123 /* GAS Initial Response */
6124 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6125 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306126
Jeff Johnson295189b2012-06-20 16:38:30 -07006127 /* GAS Comeback Request */
6128 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6129 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6130
6131 /* GAS Comeback Response */
6132 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6133 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6134
6135 /* P2P Public Action */
6136 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306137 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006138 P2P_PUBLIC_ACTION_FRAME_SIZE );
6139
6140 /* P2P Action */
6141 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6142 (v_U8_t*)P2P_ACTION_FRAME,
6143 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006144 /* WNM-Notification */
6145 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6146 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6147 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006148}
6149
6150#ifdef FEATURE_WLAN_WAPI
6151void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05306152 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006153{
6154 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6155 tCsrRoamSetKey setKey;
6156 v_BOOL_t isConnected = TRUE;
6157 int status = 0;
6158 v_U32_t roamId= 0xFF;
6159 tANI_U8 *pKeyPtr = NULL;
6160 int n = 0;
6161
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306162 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
6163 __func__, hdd_device_modetoString(pAdapter->device_mode),
6164 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006165
Gopichand Nakkalae7480202013-02-11 15:24:22 +05306166 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006167 setKey.keyId = key_index; // Store Key ID
6168 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
6169 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
6170 setKey.paeRole = 0 ; // the PAE role
6171 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
6172 {
6173 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
6174 }
6175 else
6176 {
6177 isConnected = hdd_connIsConnected(pHddStaCtx);
6178 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
6179 }
6180 setKey.keyLength = key_Len;
6181 pKeyPtr = setKey.Key;
6182 memcpy( pKeyPtr, key, key_Len);
6183
Arif Hussain6d2a3322013-11-17 19:50:10 -08006184 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07006185 __func__, key_Len);
6186 for (n = 0 ; n < key_Len; n++)
6187 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
6188 __func__,n,setKey.Key[n]);
6189
6190 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
6191 if ( isConnected )
6192 {
6193 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
6194 pAdapter->sessionId, &setKey, &roamId );
6195 }
6196 if ( status != 0 )
6197 {
6198 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6199 "[%4d] sme_RoamSetKey returned ERROR status= %d",
6200 __LINE__, status );
6201 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
6202 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05306203 /* Need to clear any trace of key value in the memory.
6204 * Thus zero out the memory even though it is local
6205 * variable.
6206 */
6207 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006208}
6209#endif /* FEATURE_WLAN_WAPI*/
6210
6211#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306212int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006213 beacon_data_t **ppBeacon,
6214 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006215#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306216int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006217 beacon_data_t **ppBeacon,
6218 struct cfg80211_beacon_data *params,
6219 int dtim_period)
6220#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306221{
Jeff Johnson295189b2012-06-20 16:38:30 -07006222 int size;
6223 beacon_data_t *beacon = NULL;
6224 beacon_data_t *old = NULL;
6225 int head_len,tail_len;
6226
Jeff Johnsone7245742012-09-05 17:12:55 -07006227 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006228 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306229 {
6230 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6231 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006232 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306233 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006234
6235 old = pAdapter->sessionCtx.ap.beacon;
6236
6237 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306238 {
6239 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6240 FL("session(%d) old and new heads points to NULL"),
6241 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006242 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306243 }
6244
6245 if (params->tail && !params->tail_len)
6246 {
6247 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6248 FL("tail_len is zero but tail is not NULL"));
6249 return -EINVAL;
6250 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006251
Jeff Johnson295189b2012-06-20 16:38:30 -07006252#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
6253 /* Kernel 3.0 is not updating dtim_period for set beacon */
6254 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306255 {
6256 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6257 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006258 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306259 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006260#endif
6261
6262 if(params->head)
6263 head_len = params->head_len;
6264 else
6265 head_len = old->head_len;
6266
6267 if(params->tail || !old)
6268 tail_len = params->tail_len;
6269 else
6270 tail_len = old->tail_len;
6271
6272 size = sizeof(beacon_data_t) + head_len + tail_len;
6273
6274 beacon = kzalloc(size, GFP_KERNEL);
6275
6276 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306277 {
6278 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6279 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006280 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306281 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006282
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006283#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006284 if(params->dtim_period || !old )
6285 beacon->dtim_period = params->dtim_period;
6286 else
6287 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006288#else
6289 if(dtim_period || !old )
6290 beacon->dtim_period = dtim_period;
6291 else
6292 beacon->dtim_period = old->dtim_period;
6293#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306294
Jeff Johnson295189b2012-06-20 16:38:30 -07006295 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6296 beacon->tail = beacon->head + head_len;
6297 beacon->head_len = head_len;
6298 beacon->tail_len = tail_len;
6299
6300 if(params->head) {
6301 memcpy (beacon->head,params->head,beacon->head_len);
6302 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306303 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07006304 if(old)
6305 memcpy (beacon->head,old->head,beacon->head_len);
6306 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306307
Jeff Johnson295189b2012-06-20 16:38:30 -07006308 if(params->tail) {
6309 memcpy (beacon->tail,params->tail,beacon->tail_len);
6310 }
6311 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306312 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07006313 memcpy (beacon->tail,old->tail,beacon->tail_len);
6314 }
6315
6316 *ppBeacon = beacon;
6317
6318 kfree(old);
6319
6320 return 0;
6321
6322}
Jeff Johnson295189b2012-06-20 16:38:30 -07006323
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05306324v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
6325#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6326 const v_U8_t *pIes,
6327#else
6328 v_U8_t *pIes,
6329#endif
6330 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006331{
6332 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05306333 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07006334 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306335
Jeff Johnson295189b2012-06-20 16:38:30 -07006336 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306337 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006338 elem_id = ptr[0];
6339 elem_len = ptr[1];
6340 left -= 2;
6341 if(elem_len > left)
6342 {
6343 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006344 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006345 eid,elem_len,left);
6346 return NULL;
6347 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306348 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006349 {
6350 return ptr;
6351 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306352
Jeff Johnson295189b2012-06-20 16:38:30 -07006353 left -= elem_len;
6354 ptr += (elem_len + 2);
6355 }
6356 return NULL;
6357}
6358
Jeff Johnson295189b2012-06-20 16:38:30 -07006359/* Check if rate is 11g rate or not */
6360static int wlan_hdd_rate_is_11g(u8 rate)
6361{
Sanjay Devnani28322e22013-06-21 16:13:40 -07006362 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006363 u8 i;
6364 for (i = 0; i < 8; i++)
6365 {
6366 if(rate == gRateArray[i])
6367 return TRUE;
6368 }
6369 return FALSE;
6370}
6371
6372/* Check for 11g rate and set proper 11g only mode */
6373static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
6374 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
6375{
6376 u8 i, num_rates = pIe[0];
6377
6378 pIe += 1;
6379 for ( i = 0; i < num_rates; i++)
6380 {
6381 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
6382 {
6383 /* If rate set have 11g rate than change the mode to 11G */
6384 *pSapHw_mode = eSAP_DOT11_MODE_11g;
6385 if (pIe[i] & BASIC_RATE_MASK)
6386 {
6387 /* If we have 11g rate as basic rate, it means mode
6388 is 11g only mode.
6389 */
6390 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
6391 *pCheckRatesfor11g = FALSE;
6392 }
6393 }
6394 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
6395 {
6396 *require_ht = TRUE;
6397 }
6398 }
6399 return;
6400}
6401
6402static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
6403{
6404 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6405 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6406 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6407 u8 checkRatesfor11g = TRUE;
6408 u8 require_ht = FALSE;
6409 u8 *pIe=NULL;
6410
6411 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
6412
6413 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
6414 pBeacon->head_len, WLAN_EID_SUPP_RATES);
6415 if (pIe != NULL)
6416 {
6417 pIe += 1;
6418 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6419 &pConfig->SapHw_mode);
6420 }
6421
6422 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6423 WLAN_EID_EXT_SUPP_RATES);
6424 if (pIe != NULL)
6425 {
6426
6427 pIe += 1;
6428 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6429 &pConfig->SapHw_mode);
6430 }
6431
6432 if( pConfig->channel > 14 )
6433 {
6434 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
6435 }
6436
6437 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6438 WLAN_EID_HT_CAPABILITY);
6439
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306440 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006441 {
6442 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
6443 if(require_ht)
6444 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
6445 }
6446}
6447
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306448static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
6449 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
6450{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006451 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306452 v_U8_t *pIe = NULL;
6453 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6454
6455 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
6456 pBeacon->tail, pBeacon->tail_len);
6457
6458 if (pIe)
6459 {
6460 ielen = pIe[1] + 2;
6461 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6462 {
6463 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
6464 }
6465 else
6466 {
6467 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
6468 return -EINVAL;
6469 }
6470 *total_ielen += ielen;
6471 }
6472 return 0;
6473}
6474
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006475static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
6476 v_U8_t *genie, v_U8_t *total_ielen)
6477{
6478 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6479 int left = pBeacon->tail_len;
6480 v_U8_t *ptr = pBeacon->tail;
6481 v_U8_t elem_id, elem_len;
6482 v_U16_t ielen = 0;
6483
6484 if ( NULL == ptr || 0 == left )
6485 return;
6486
6487 while (left >= 2)
6488 {
6489 elem_id = ptr[0];
6490 elem_len = ptr[1];
6491 left -= 2;
6492 if (elem_len > left)
6493 {
6494 hddLog( VOS_TRACE_LEVEL_ERROR,
6495 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
6496 elem_id, elem_len, left);
6497 return;
6498 }
6499 if (IE_EID_VENDOR == elem_id)
6500 {
6501 /* skipping the VSIE's which we don't want to include or
6502 * it will be included by existing code
6503 */
6504 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
6505#ifdef WLAN_FEATURE_WFD
6506 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
6507#endif
6508 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6509 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6510 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
6511 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6512 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
6513 {
6514 ielen = ptr[1] + 2;
6515 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6516 {
6517 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
6518 *total_ielen += ielen;
6519 }
6520 else
6521 {
6522 hddLog( VOS_TRACE_LEVEL_ERROR,
6523 "IE Length is too big "
6524 "IEs eid=%d elem_len=%d total_ie_lent=%d",
6525 elem_id, elem_len, *total_ielen);
6526 }
6527 }
6528 }
6529
6530 left -= elem_len;
6531 ptr += (elem_len + 2);
6532 }
6533 return;
6534}
6535
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006536#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006537static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6538 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006539#else
6540static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6541 struct cfg80211_beacon_data *params)
6542#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006543{
6544 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306545 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006546 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07006547 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006548
6549 genie = vos_mem_malloc(MAX_GENIE_LEN);
6550
6551 if(genie == NULL) {
6552
6553 return -ENOMEM;
6554 }
6555
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306556 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6557 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006558 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306559 hddLog(LOGE,
6560 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306561 ret = -EINVAL;
6562 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006563 }
6564
6565#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306566 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6567 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
6568 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306569 hddLog(LOGE,
6570 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306571 ret = -EINVAL;
6572 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006573 }
6574#endif
6575
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306576 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6577 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006578 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306579 hddLog(LOGE,
6580 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306581 ret = -EINVAL;
6582 goto done;
6583 }
6584
6585 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
6586 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006587 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07006588 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006589
6590 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6591 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
6592 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
6593 {
6594 hddLog(LOGE,
6595 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006596 ret = -EINVAL;
6597 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006598 }
6599
6600 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6601 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6602 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6603 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6604 ==eHAL_STATUS_FAILURE)
6605 {
6606 hddLog(LOGE,
6607 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006608 ret = -EINVAL;
6609 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006610 }
6611
6612 // Added for ProResp IE
6613 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
6614 {
6615 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
6616 u8 probe_rsp_ie_len[3] = {0};
6617 u8 counter = 0;
6618 /* Check Probe Resp Length if it is greater then 255 then Store
6619 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
6620 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
6621 Store More then 255 bytes into One Variable.
6622 */
6623 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6624 {
6625 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6626 {
6627 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6628 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6629 }
6630 else
6631 {
6632 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6633 rem_probe_resp_ie_len = 0;
6634 }
6635 }
6636
6637 rem_probe_resp_ie_len = 0;
6638
6639 if (probe_rsp_ie_len[0] > 0)
6640 {
6641 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6642 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6643 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6644 probe_rsp_ie_len[0], NULL,
6645 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6646 {
6647 hddLog(LOGE,
6648 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006649 ret = -EINVAL;
6650 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006651 }
6652 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6653 }
6654
6655 if (probe_rsp_ie_len[1] > 0)
6656 {
6657 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6658 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6659 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6660 probe_rsp_ie_len[1], NULL,
6661 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6662 {
6663 hddLog(LOGE,
6664 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 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[1];
6669 }
6670
6671 if (probe_rsp_ie_len[2] > 0)
6672 {
6673 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6674 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6675 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6676 probe_rsp_ie_len[2], NULL,
6677 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6678 {
6679 hddLog(LOGE,
6680 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 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[2];
6685 }
6686
6687 if (probe_rsp_ie_len[1] == 0 )
6688 {
6689 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6690 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6691 eANI_BOOLEAN_FALSE) )
6692 {
6693 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006694 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006695 }
6696 }
6697
6698 if (probe_rsp_ie_len[2] == 0 )
6699 {
6700 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6701 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6702 eANI_BOOLEAN_FALSE) )
6703 {
6704 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006705 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006706 }
6707 }
6708
6709 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6710 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6711 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6712 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6713 == eHAL_STATUS_FAILURE)
6714 {
6715 hddLog(LOGE,
6716 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006717 ret = -EINVAL;
6718 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006719 }
6720 }
6721 else
6722 {
6723 // Reset WNI_CFG_PROBE_RSP Flags
6724 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
6725
6726 hddLog(VOS_TRACE_LEVEL_INFO,
6727 "%s: No Probe Response IE received in set beacon",
6728 __func__);
6729 }
6730
6731 // Added for AssocResp IE
6732 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
6733 {
6734 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6735 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
6736 params->assocresp_ies_len, NULL,
6737 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6738 {
6739 hddLog(LOGE,
6740 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006741 ret = -EINVAL;
6742 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006743 }
6744
6745 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6746 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
6747 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6748 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6749 == eHAL_STATUS_FAILURE)
6750 {
6751 hddLog(LOGE,
6752 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006753 ret = -EINVAL;
6754 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006755 }
6756 }
6757 else
6758 {
6759 hddLog(VOS_TRACE_LEVEL_INFO,
6760 "%s: No Assoc Response IE received in set beacon",
6761 __func__);
6762
6763 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6764 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6765 eANI_BOOLEAN_FALSE) )
6766 {
6767 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006768 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006769 }
6770 }
6771
Jeff Johnsone7245742012-09-05 17:12:55 -07006772done:
Jeff Johnson295189b2012-06-20 16:38:30 -07006773 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306774 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006775}
Jeff Johnson295189b2012-06-20 16:38:30 -07006776
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306777/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006778 * FUNCTION: wlan_hdd_validate_operation_channel
6779 * called by wlan_hdd_cfg80211_start_bss() and
6780 * wlan_hdd_cfg80211_set_channel()
6781 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306782 * channel list.
6783 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006784VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006785{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306786
Jeff Johnson295189b2012-06-20 16:38:30 -07006787 v_U32_t num_ch = 0;
6788 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6789 u32 indx = 0;
6790 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306791 v_U8_t fValidChannel = FALSE, count = 0;
6792 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306793
Jeff Johnson295189b2012-06-20 16:38:30 -07006794 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6795
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306796 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006797 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306798 /* Validate the channel */
6799 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006800 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306801 if ( channel == rfChannels[count].channelNum )
6802 {
6803 fValidChannel = TRUE;
6804 break;
6805 }
6806 }
6807 if (fValidChannel != TRUE)
6808 {
6809 hddLog(VOS_TRACE_LEVEL_ERROR,
6810 "%s: Invalid Channel [%d]", __func__, channel);
6811 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006812 }
6813 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306814 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006815 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306816 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6817 valid_ch, &num_ch))
6818 {
6819 hddLog(VOS_TRACE_LEVEL_ERROR,
6820 "%s: failed to get valid channel list", __func__);
6821 return VOS_STATUS_E_FAILURE;
6822 }
6823 for (indx = 0; indx < num_ch; indx++)
6824 {
6825 if (channel == valid_ch[indx])
6826 {
6827 break;
6828 }
6829 }
6830
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306831 if (indx >= num_ch)
6832 {
6833 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6834 {
6835 eCsrBand band;
6836 unsigned int freq;
6837
6838 sme_GetFreqBand(hHal, &band);
6839
6840 if (eCSR_BAND_5G == band)
6841 {
6842#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
6843 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
6844 {
6845 freq = ieee80211_channel_to_frequency(channel,
6846 IEEE80211_BAND_2GHZ);
6847 }
6848 else
6849 {
6850 freq = ieee80211_channel_to_frequency(channel,
6851 IEEE80211_BAND_5GHZ);
6852 }
6853#else
6854 freq = ieee80211_channel_to_frequency(channel);
6855#endif
6856 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
6857 return VOS_STATUS_SUCCESS;
6858 }
6859 }
6860
6861 hddLog(VOS_TRACE_LEVEL_ERROR,
6862 "%s: Invalid Channel [%d]", __func__, channel);
6863 return VOS_STATUS_E_FAILURE;
6864 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006865 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306866
Jeff Johnson295189b2012-06-20 16:38:30 -07006867 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306868
Jeff Johnson295189b2012-06-20 16:38:30 -07006869}
6870
Viral Modi3a32cc52013-02-08 11:14:52 -08006871/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306872 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08006873 * This function is used to set the channel number
6874 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306875static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08006876 struct ieee80211_channel *chan,
6877 enum nl80211_channel_type channel_type
6878 )
6879{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306880 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08006881 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07006882 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08006883 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306884 hdd_context_t *pHddCtx;
6885 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006886
6887 ENTER();
6888
6889 if( NULL == dev )
6890 {
6891 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006892 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006893 return -ENODEV;
6894 }
6895 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306896
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306897 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6898 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
6899 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08006900 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306901 "%s: device_mode = %s (%d) freq = %d", __func__,
6902 hdd_device_modetoString(pAdapter->device_mode),
6903 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306904
6905 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6906 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306907 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08006908 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306909 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006910 }
6911
6912 /*
6913 * Do freq to chan conversion
6914 * TODO: for 11a
6915 */
6916
6917 channel = ieee80211_frequency_to_channel(freq);
6918
6919 /* Check freq range */
6920 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6921 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
6922 {
6923 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006924 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08006925 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6926 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6927 return -EINVAL;
6928 }
6929
6930 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6931
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05306932 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6933 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08006934 {
6935 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
6936 {
6937 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006938 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08006939 return -EINVAL;
6940 }
6941 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6942 "%s: set channel to [%d] for device mode =%d",
6943 __func__, channel,pAdapter->device_mode);
6944 }
6945 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08006946 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08006947 )
6948 {
6949 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6950 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
6951 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6952
6953 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
6954 {
6955 /* Link is up then return cant set channel*/
6956 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006957 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006958 return -EINVAL;
6959 }
6960
6961 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6962 pHddStaCtx->conn_info.operationChannel = channel;
6963 pRoamProfile->ChannelInfo.ChannelList =
6964 &pHddStaCtx->conn_info.operationChannel;
6965 }
6966 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08006967 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08006968 )
6969 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306970 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6971 {
6972 if(VOS_STATUS_SUCCESS !=
6973 wlan_hdd_validate_operation_channel(pAdapter,channel))
6974 {
6975 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006976 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306977 return -EINVAL;
6978 }
6979 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6980 }
6981 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08006982 {
6983 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
6984
6985 /* If auto channel selection is configured as enable/ 1 then ignore
6986 channel set by supplicant
6987 */
6988 if ( cfg_param->apAutoChannelSelection )
6989 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306990 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
6991 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08006992 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306993 "%s: set channel to auto channel (0) for device mode =%s (%d)",
6994 __func__, hdd_device_modetoString(pAdapter->device_mode),
6995 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08006996 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306997 else
6998 {
6999 if(VOS_STATUS_SUCCESS !=
7000 wlan_hdd_validate_operation_channel(pAdapter,channel))
7001 {
7002 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007003 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307004 return -EINVAL;
7005 }
7006 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7007 }
Viral Modi3a32cc52013-02-08 11:14:52 -08007008 }
7009 }
7010 else
7011 {
7012 hddLog(VOS_TRACE_LEVEL_FATAL,
7013 "%s: Invalid device mode failed to set valid channel", __func__);
7014 return -EINVAL;
7015 }
7016 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307017 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007018}
7019
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307020static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
7021 struct net_device *dev,
7022 struct ieee80211_channel *chan,
7023 enum nl80211_channel_type channel_type
7024 )
7025{
7026 int ret;
7027
7028 vos_ssr_protect(__func__);
7029 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
7030 vos_ssr_unprotect(__func__);
7031
7032 return ret;
7033}
7034
Jeff Johnson295189b2012-06-20 16:38:30 -07007035#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7036static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7037 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007038#else
7039static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7040 struct cfg80211_beacon_data *params,
7041 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307042 enum nl80211_hidden_ssid hidden_ssid,
7043 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007044#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007045{
7046 tsap_Config_t *pConfig;
7047 beacon_data_t *pBeacon = NULL;
7048 struct ieee80211_mgmt *pMgmt_frame;
7049 v_U8_t *pIe=NULL;
7050 v_U16_t capab_info;
7051 eCsrAuthType RSNAuthType;
7052 eCsrEncryptionType RSNEncryptType;
7053 eCsrEncryptionType mcRSNEncryptType;
7054 int status = VOS_STATUS_SUCCESS;
7055 tpWLAN_SAPEventCB pSapEventCallback;
7056 hdd_hostapd_state_t *pHostapdState;
7057 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
7058 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307059 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007060 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307061 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07007062 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08007063 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05307064 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07007065 v_BOOL_t MFPCapable = VOS_FALSE;
7066 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307067 v_BOOL_t sapEnable11AC =
7068 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07007069 ENTER();
7070
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307071 iniConfig = pHddCtx->cfg_ini;
7072
Jeff Johnson295189b2012-06-20 16:38:30 -07007073 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
7074
7075 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7076
7077 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7078
7079 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
7080
7081 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
7082
7083 //channel is already set in the set_channel Call back
7084 //pConfig->channel = pCommitConfig->channel;
7085
7086 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307087 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07007088 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
7089
7090 pConfig->dtim_period = pBeacon->dtim_period;
7091
Arif Hussain6d2a3322013-11-17 19:50:10 -08007092 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07007093 pConfig->dtim_period);
7094
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08007095 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07007096 {
7097 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007098 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05307099 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
7100 {
7101 tANI_BOOLEAN restartNeeded;
7102 pConfig->ieee80211d = 1;
7103 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
7104 sme_setRegInfo(hHal, pConfig->countryCode);
7105 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
7106 }
7107 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07007108 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07007109 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07007110 pConfig->ieee80211d = 1;
7111 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
7112 sme_setRegInfo(hHal, pConfig->countryCode);
7113 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07007114 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007115 else
7116 {
7117 pConfig->ieee80211d = 0;
7118 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307119 /*
7120 * If auto channel is configured i.e. channel is 0,
7121 * so skip channel validation.
7122 */
7123 if( AUTO_CHANNEL_SELECT != pConfig->channel )
7124 {
7125 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
7126 {
7127 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007128 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307129 return -EINVAL;
7130 }
7131 }
7132 else
7133 {
7134 if(1 != pHddCtx->is_dynamic_channel_range_set)
7135 {
7136 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
7137 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
7138 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
7139 }
7140 pHddCtx->is_dynamic_channel_range_set = 0;
7141 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007142 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007143 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007144 {
7145 pConfig->ieee80211d = 0;
7146 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307147
7148#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7149 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7150 pConfig->authType = eSAP_OPEN_SYSTEM;
7151 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7152 pConfig->authType = eSAP_SHARED_KEY;
7153 else
7154 pConfig->authType = eSAP_AUTO_SWITCH;
7155#else
7156 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7157 pConfig->authType = eSAP_OPEN_SYSTEM;
7158 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7159 pConfig->authType = eSAP_SHARED_KEY;
7160 else
7161 pConfig->authType = eSAP_AUTO_SWITCH;
7162#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007163
7164 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307165
7166 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07007167 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
7168
7169 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
7170
7171 /*Set wps station to configured*/
7172 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
7173
7174 if(pIe)
7175 {
7176 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
7177 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007178 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07007179 return -EINVAL;
7180 }
7181 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
7182 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007183 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07007184 /* Check 15 bit of WPS IE as it contain information for wps state
7185 * WPS state
7186 */
7187 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
7188 {
7189 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
7190 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
7191 {
7192 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
7193 }
7194 }
7195 }
7196 else
7197 {
7198 pConfig->wps_state = SAP_WPS_DISABLED;
7199 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307200 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07007201
c_hpothufe599e92014-06-16 11:38:55 +05307202 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7203 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7204 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
7205 eCSR_ENCRYPT_TYPE_NONE;
7206
Jeff Johnson295189b2012-06-20 16:38:30 -07007207 pConfig->RSNWPAReqIELength = 0;
7208 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307209 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007210 WLAN_EID_RSN);
7211 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307212 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007213 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7214 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7215 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307216 /* The actual processing may eventually be more extensive than
7217 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07007218 * by the app.
7219 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307220 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007221 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7222 &RSNEncryptType,
7223 &mcRSNEncryptType,
7224 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007225 &MFPCapable,
7226 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007227 pConfig->pRSNWPAReqIE[1]+2,
7228 pConfig->pRSNWPAReqIE );
7229
7230 if( VOS_STATUS_SUCCESS == status )
7231 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307232 /* Now copy over all the security attributes you have
7233 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007234 * */
7235 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7236 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7237 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7238 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307239 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007240 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007241 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7242 }
7243 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307244
Jeff Johnson295189b2012-06-20 16:38:30 -07007245 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7246 pBeacon->tail, pBeacon->tail_len);
7247
7248 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
7249 {
7250 if (pConfig->pRSNWPAReqIE)
7251 {
7252 /*Mixed mode WPA/WPA2*/
7253 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
7254 pConfig->RSNWPAReqIELength += pIe[1] + 2;
7255 }
7256 else
7257 {
7258 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7259 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7260 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307261 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007262 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7263 &RSNEncryptType,
7264 &mcRSNEncryptType,
7265 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007266 &MFPCapable,
7267 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007268 pConfig->pRSNWPAReqIE[1]+2,
7269 pConfig->pRSNWPAReqIE );
7270
7271 if( VOS_STATUS_SUCCESS == status )
7272 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307273 /* Now copy over all the security attributes you have
7274 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007275 * */
7276 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7277 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7278 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7279 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307280 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007281 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007282 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7283 }
7284 }
7285 }
7286
Jeff Johnson4416a782013-03-25 14:17:50 -07007287 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
7288 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
7289 return -EINVAL;
7290 }
7291
Jeff Johnson295189b2012-06-20 16:38:30 -07007292 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
7293
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007294#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007295 if (params->ssid != NULL)
7296 {
7297 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
7298 pConfig->SSIDinfo.ssid.length = params->ssid_len;
7299 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7300 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7301 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007302#else
7303 if (ssid != NULL)
7304 {
7305 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
7306 pConfig->SSIDinfo.ssid.length = ssid_len;
7307 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7308 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7309 }
7310#endif
7311
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307312 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07007313 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307314
Jeff Johnson295189b2012-06-20 16:38:30 -07007315 /* default value */
7316 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7317 pConfig->num_accept_mac = 0;
7318 pConfig->num_deny_mac = 0;
7319
7320 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7321 pBeacon->tail, pBeacon->tail_len);
7322
7323 /* pIe for black list is following form:
7324 type : 1 byte
7325 length : 1 byte
7326 OUI : 4 bytes
7327 acl type : 1 byte
7328 no of mac addr in black list: 1 byte
7329 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307330 */
7331 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007332 {
7333 pConfig->SapMacaddr_acl = pIe[6];
7334 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007335 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007336 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307337 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
7338 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007339 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7340 for (i = 0; i < pConfig->num_deny_mac; i++)
7341 {
7342 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7343 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307344 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007345 }
7346 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7347 pBeacon->tail, pBeacon->tail_len);
7348
7349 /* pIe for white list is following form:
7350 type : 1 byte
7351 length : 1 byte
7352 OUI : 4 bytes
7353 acl type : 1 byte
7354 no of mac addr in white list: 1 byte
7355 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307356 */
7357 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007358 {
7359 pConfig->SapMacaddr_acl = pIe[6];
7360 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007361 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007362 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307363 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
7364 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007365 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7366 for (i = 0; i < pConfig->num_accept_mac; i++)
7367 {
7368 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7369 acl_entry++;
7370 }
7371 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307372
Jeff Johnson295189b2012-06-20 16:38:30 -07007373 wlan_hdd_set_sapHwmode(pHostapdAdapter);
7374
Jeff Johnsone7245742012-09-05 17:12:55 -07007375#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007376 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307377 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
7378 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05307379 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
7380 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007381 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
7382 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307383 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
7384 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07007385 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307386 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07007387 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307388 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007389
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307390 /* If ACS disable and selected channel <= 14
7391 * OR
7392 * ACS enabled and ACS operating band is choosen as 2.4
7393 * AND
7394 * VHT in 2.4G Disabled
7395 * THEN
7396 * Fallback to 11N mode
7397 */
7398 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
7399 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05307400 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307401 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007402 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307403 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
7404 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007405 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
7406 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007407 }
7408#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307409
Jeff Johnson295189b2012-06-20 16:38:30 -07007410 // ht_capab is not what the name conveys,this is used for protection bitmap
7411 pConfig->ht_capab =
7412 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
7413
7414 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
7415 {
7416 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
7417 return -EINVAL;
7418 }
7419
7420 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307421 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07007422 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
7423 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307424 pConfig->obssProtEnabled =
7425 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07007426
Chet Lanctot8cecea22014-02-11 19:09:36 -08007427#ifdef WLAN_FEATURE_11W
7428 pConfig->mfpCapable = MFPCapable;
7429 pConfig->mfpRequired = MFPRequired;
7430 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
7431 pConfig->mfpCapable, pConfig->mfpRequired);
7432#endif
7433
Arif Hussain6d2a3322013-11-17 19:50:10 -08007434 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07007435 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007436 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
7437 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
7438 (int)pConfig->channel);
7439 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
7440 pConfig->SapHw_mode, pConfig->privacy,
7441 pConfig->authType);
7442 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
7443 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
7444 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
7445 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07007446
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307447 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007448 {
7449 //Bss already started. just return.
7450 //TODO Probably it should update some beacon params.
7451 hddLog( LOGE, "Bss Already started...Ignore the request");
7452 EXIT();
7453 return 0;
7454 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307455
Agarwal Ashish51325b52014-06-16 16:50:49 +05307456 if (vos_max_concurrent_connections_reached()) {
7457 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7458 return -EINVAL;
7459 }
7460
Jeff Johnson295189b2012-06-20 16:38:30 -07007461 pConfig->persona = pHostapdAdapter->device_mode;
7462
Peng Xu2446a892014-09-05 17:21:18 +05307463 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
7464 if ( NULL != psmeConfig)
7465 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307466 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05307467 sme_GetConfigParam(hHal, psmeConfig);
7468 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307469#ifdef WLAN_FEATURE_AP_HT40_24G
7470 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
7471 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
7472 && pHddCtx->cfg_ini->apHT40_24GEnabled)
7473 {
7474 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
7475 sme_UpdateConfig (hHal, psmeConfig);
7476 }
7477#endif
Peng Xu2446a892014-09-05 17:21:18 +05307478 vos_mem_free(psmeConfig);
7479 }
Peng Xuafc34e32014-09-25 13:23:55 +05307480 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05307481
Jeff Johnson295189b2012-06-20 16:38:30 -07007482 pSapEventCallback = hdd_hostapd_SAPEventCB;
7483 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
7484 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
7485 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007486 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007487 return -EINVAL;
7488 }
7489
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307490 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07007491 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
7492
7493 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307494
Jeff Johnson295189b2012-06-20 16:38:30 -07007495 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307496 {
7497 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007498 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07007499 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07007500 VOS_ASSERT(0);
7501 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307502
Jeff Johnson295189b2012-06-20 16:38:30 -07007503 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05307504 /* Initialize WMM configuation */
7505 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307506 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007507
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007508#ifdef WLAN_FEATURE_P2P_DEBUG
7509 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
7510 {
7511 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
7512 {
7513 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7514 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007515 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007516 }
7517 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
7518 {
7519 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7520 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007521 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007522 }
7523 }
7524#endif
7525
Jeff Johnson295189b2012-06-20 16:38:30 -07007526 pHostapdState->bCommit = TRUE;
7527 EXIT();
7528
7529 return 0;
7530}
7531
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007532#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307533static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307534 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007535 struct beacon_parameters *params)
7536{
7537 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307538 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307539 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007540
7541 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307542
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307543 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7544 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
7545 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307546 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
7547 hdd_device_modetoString(pAdapter->device_mode),
7548 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007549
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307550 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7551 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307552 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007553 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307554 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007555 }
7556
Agarwal Ashish51325b52014-06-16 16:50:49 +05307557 if (vos_max_concurrent_connections_reached()) {
7558 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7559 return -EINVAL;
7560 }
7561
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307562 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007563 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007564 )
7565 {
7566 beacon_data_t *old,*new;
7567
7568 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307569
Jeff Johnson295189b2012-06-20 16:38:30 -07007570 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307571 {
7572 hddLog(VOS_TRACE_LEVEL_WARN,
7573 FL("already beacon info added to session(%d)"),
7574 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007575 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307576 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007577
7578 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7579
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307580 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07007581 {
7582 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007583 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007584 return -EINVAL;
7585 }
7586
7587 pAdapter->sessionCtx.ap.beacon = new;
7588
7589 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7590 }
7591
7592 EXIT();
7593 return status;
7594}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307595
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307596static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
7597 struct net_device *dev,
7598 struct beacon_parameters *params)
7599{
7600 int ret;
7601
7602 vos_ssr_protect(__func__);
7603 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
7604 vos_ssr_unprotect(__func__);
7605
7606 return ret;
7607}
7608
7609static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007610 struct net_device *dev,
7611 struct beacon_parameters *params)
7612{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307613 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307614 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7615 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307616 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007617
7618 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307619
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307620 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7621 TRACE_CODE_HDD_CFG80211_SET_BEACON,
7622 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
7623 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7624 __func__, hdd_device_modetoString(pAdapter->device_mode),
7625 pAdapter->device_mode);
7626
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307627 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7628 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307629 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007630 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307631 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007632 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307633
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307634 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007635 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307636 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007637 {
7638 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307639
Jeff Johnson295189b2012-06-20 16:38:30 -07007640 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307641
Jeff Johnson295189b2012-06-20 16:38:30 -07007642 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307643 {
7644 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7645 FL("session(%d) old and new heads points to NULL"),
7646 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007647 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307648 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007649
7650 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7651
7652 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307653 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007654 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007655 return -EINVAL;
7656 }
7657
7658 pAdapter->sessionCtx.ap.beacon = new;
7659
7660 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7661 }
7662
7663 EXIT();
7664 return status;
7665}
7666
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307667static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
7668 struct net_device *dev,
7669 struct beacon_parameters *params)
7670{
7671 int ret;
7672
7673 vos_ssr_protect(__func__);
7674 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
7675 vos_ssr_unprotect(__func__);
7676
7677 return ret;
7678}
7679
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007680#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7681
7682#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307683static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007684 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007685#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307686static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007687 struct net_device *dev)
7688#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007689{
7690 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07007691 hdd_context_t *pHddCtx = NULL;
7692 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307693 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307694 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007695
7696 ENTER();
7697
7698 if (NULL == pAdapter)
7699 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307700 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007701 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007702 return -ENODEV;
7703 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007704
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307705 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7706 TRACE_CODE_HDD_CFG80211_STOP_AP,
7707 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307708 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7709 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307710 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007711 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307712 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07007713 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007714
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007715 pScanInfo = &pHddCtx->scan_info;
7716
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307717 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7718 __func__, hdd_device_modetoString(pAdapter->device_mode),
7719 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007720
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307721 ret = wlan_hdd_scan_abort(pAdapter);
7722
Girish Gowli4bf7a632014-06-12 13:42:11 +05307723 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07007724 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307725 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7726 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307727
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307728 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07007729 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307730 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7731 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08007732
Jeff Johnsone7245742012-09-05 17:12:55 -07007733 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307734 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07007735 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307736 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07007737 }
7738
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05307739 /* Delete all associated STAs before stopping AP/P2P GO */
7740 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05307741 hdd_hostapd_stop(dev);
7742
Jeff Johnson295189b2012-06-20 16:38:30 -07007743 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007744 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007745 )
7746 {
7747 beacon_data_t *old;
7748
7749 old = pAdapter->sessionCtx.ap.beacon;
7750
7751 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307752 {
7753 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7754 FL("session(%d) beacon data points to NULL"),
7755 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007756 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307757 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007758
Jeff Johnson295189b2012-06-20 16:38:30 -07007759 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007760
7761 mutex_lock(&pHddCtx->sap_lock);
7762 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7763 {
Jeff Johnson4416a782013-03-25 14:17:50 -07007764 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007765 {
7766 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7767
7768 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7769
7770 if (!VOS_IS_STATUS_SUCCESS(status))
7771 {
7772 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007773 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007774 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307775 }
7776 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007777 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307778 /* BSS stopped, clear the active sessions for this device mode */
7779 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007780 }
7781 mutex_unlock(&pHddCtx->sap_lock);
7782
7783 if(status != VOS_STATUS_SUCCESS)
7784 {
7785 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007786 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007787 return -EINVAL;
7788 }
7789
Jeff Johnson4416a782013-03-25 14:17:50 -07007790 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007791 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
7792 ==eHAL_STATUS_FAILURE)
7793 {
7794 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007795 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007796 }
7797
Jeff Johnson4416a782013-03-25 14:17:50 -07007798 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007799 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7800 eANI_BOOLEAN_FALSE) )
7801 {
7802 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007803 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007804 }
7805
7806 // Reset WNI_CFG_PROBE_RSP Flags
7807 wlan_hdd_reset_prob_rspies(pAdapter);
7808
7809 pAdapter->sessionCtx.ap.beacon = NULL;
7810 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007811#ifdef WLAN_FEATURE_P2P_DEBUG
7812 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
7813 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
7814 {
7815 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
7816 "GO got removed");
7817 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
7818 }
7819#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007820 }
7821 EXIT();
7822 return status;
7823}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007824
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307825#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7826static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
7827 struct net_device *dev)
7828{
7829 int ret;
7830
7831 vos_ssr_protect(__func__);
7832 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
7833 vos_ssr_unprotect(__func__);
7834
7835 return ret;
7836}
7837#else
7838static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7839 struct net_device *dev)
7840{
7841 int ret;
7842
7843 vos_ssr_protect(__func__);
7844 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
7845 vos_ssr_unprotect(__func__);
7846
7847 return ret;
7848}
7849#endif
7850
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007851#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
7852
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307853static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307854 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007855 struct cfg80211_ap_settings *params)
7856{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307857 hdd_adapter_t *pAdapter;
7858 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307859 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007860
7861 ENTER();
7862
Girish Gowlib143d7a2015-02-18 19:39:55 +05307863 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007864 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307865 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05307866 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307867 return -ENODEV;
7868 }
7869
7870 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7871 if (NULL == pAdapter)
7872 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307873 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307874 "%s: HDD adapter is Null", __func__);
7875 return -ENODEV;
7876 }
7877
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307878 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7879 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
7880 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307881 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7882 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307883 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307884 "%s: HDD adapter magic is invalid", __func__);
7885 return -ENODEV;
7886 }
7887
7888 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307889 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307890 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307891 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307892 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307893 }
7894
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307895 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
7896 __func__, hdd_device_modetoString(pAdapter->device_mode),
7897 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307898
7899 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007900 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007901 )
7902 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307903 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007904
7905 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307906
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007907 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307908 {
7909 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
7910 FL("already beacon info added to session(%d)"),
7911 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007912 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307913 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007914
Girish Gowlib143d7a2015-02-18 19:39:55 +05307915#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7916 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7917 &new,
7918 &params->beacon);
7919#else
7920 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7921 &new,
7922 &params->beacon,
7923 params->dtim_period);
7924#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007925
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307926 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007927 {
7928 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307929 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007930 return -EINVAL;
7931 }
7932 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08007933#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07007934 wlan_hdd_cfg80211_set_channel(wiphy, dev,
7935#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
7936 params->channel, params->channel_type);
7937#else
7938 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
7939#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08007940#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007941 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307942 params->ssid_len, params->hidden_ssid,
7943 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007944 }
7945
7946 EXIT();
7947 return status;
7948}
7949
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307950static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
7951 struct net_device *dev,
7952 struct cfg80211_ap_settings *params)
7953{
7954 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007955
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307956 vos_ssr_protect(__func__);
7957 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
7958 vos_ssr_unprotect(__func__);
7959
7960 return ret;
7961}
7962
7963static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007964 struct net_device *dev,
7965 struct cfg80211_beacon_data *params)
7966{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307967 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307968 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307969 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007970
7971 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307972
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307973 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7974 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
7975 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007976 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007977 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307978
7979 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7980 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307981 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007982 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307983 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007984 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007985
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307986 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007987 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307988 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007989 {
7990 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307991
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007992 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307993
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007994 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307995 {
7996 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7997 FL("session(%d) beacon data points to NULL"),
7998 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007999 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308000 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008001
8002 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
8003
8004 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308005 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008006 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008007 return -EINVAL;
8008 }
8009
8010 pAdapter->sessionCtx.ap.beacon = new;
8011
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308012 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
8013 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008014 }
8015
8016 EXIT();
8017 return status;
8018}
8019
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308020static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8021 struct net_device *dev,
8022 struct cfg80211_beacon_data *params)
8023{
8024 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008025
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308026 vos_ssr_protect(__func__);
8027 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
8028 vos_ssr_unprotect(__func__);
8029
8030 return ret;
8031}
8032
8033#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008034
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308035static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008036 struct net_device *dev,
8037 struct bss_parameters *params)
8038{
8039 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308040 hdd_context_t *pHddCtx;
8041 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008042
8043 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308044
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308045 if (NULL == pAdapter)
8046 {
8047 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8048 "%s: HDD adapter is Null", __func__);
8049 return -ENODEV;
8050 }
8051 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308052 ret = wlan_hdd_validate_context(pHddCtx);
8053 if (0 != ret)
8054 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308055 return ret;
8056 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308057 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8058 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
8059 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308060 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8061 __func__, hdd_device_modetoString(pAdapter->device_mode),
8062 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008063
8064 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008065 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308066 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008067 {
8068 /* ap_isolate == -1 means that in change bss, upper layer doesn't
8069 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308070 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07008071 {
8072 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308073 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008074 }
8075
8076 EXIT();
8077 return 0;
8078}
8079
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308080static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
8081 struct net_device *dev,
8082 struct bss_parameters *params)
8083{
8084 int ret;
8085
8086 vos_ssr_protect(__func__);
8087 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
8088 vos_ssr_unprotect(__func__);
8089
8090 return ret;
8091}
Kiet Lam10841362013-11-01 11:36:50 +05308092/* FUNCTION: wlan_hdd_change_country_code_cd
8093* to wait for contry code completion
8094*/
8095void* wlan_hdd_change_country_code_cb(void *pAdapter)
8096{
8097 hdd_adapter_t *call_back_pAdapter = pAdapter;
8098 complete(&call_back_pAdapter->change_country_code);
8099 return NULL;
8100}
8101
Jeff Johnson295189b2012-06-20 16:38:30 -07008102/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308103 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07008104 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
8105 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308106int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008107 struct net_device *ndev,
8108 enum nl80211_iftype type,
8109 u32 *flags,
8110 struct vif_params *params
8111 )
8112{
8113 struct wireless_dev *wdev;
8114 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008115 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07008116 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008117 tCsrRoamProfile *pRoamProfile = NULL;
8118 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308119 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008120 eMib_dot11DesiredBssType connectedBssType;
8121 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308122 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008123
8124 ENTER();
8125
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308126 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008127 {
8128 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8129 "%s: Adapter context is null", __func__);
8130 return VOS_STATUS_E_FAILURE;
8131 }
8132
8133 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8134 if (!pHddCtx)
8135 {
8136 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8137 "%s: HDD context is null", __func__);
8138 return VOS_STATUS_E_FAILURE;
8139 }
8140
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308141 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8142 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
8143 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308144 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308145 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07008146 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308147 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008148 }
8149
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308150 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8151 __func__, hdd_device_modetoString(pAdapter->device_mode),
8152 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008153
Agarwal Ashish51325b52014-06-16 16:50:49 +05308154 if (vos_max_concurrent_connections_reached()) {
8155 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8156 return -EINVAL;
8157 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308158 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07008159 wdev = ndev->ieee80211_ptr;
8160
8161#ifdef WLAN_BTAMP_FEATURE
8162 if((NL80211_IFTYPE_P2P_CLIENT == type)||
8163 (NL80211_IFTYPE_ADHOC == type)||
8164 (NL80211_IFTYPE_AP == type)||
8165 (NL80211_IFTYPE_P2P_GO == type))
8166 {
8167 pHddCtx->isAmpAllowed = VOS_FALSE;
8168 // stop AMP traffic
8169 status = WLANBAP_StopAmp();
8170 if(VOS_STATUS_SUCCESS != status )
8171 {
8172 pHddCtx->isAmpAllowed = VOS_TRUE;
8173 hddLog(VOS_TRACE_LEVEL_FATAL,
8174 "%s: Failed to stop AMP", __func__);
8175 return -EINVAL;
8176 }
8177 }
8178#endif //WLAN_BTAMP_FEATURE
8179 /* Reset the current device mode bit mask*/
8180 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8181
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +05308182 /* Notify Mode change in case of concurrency.
8183 * Below function invokes TDLS teardown Functionality Since TDLS is
8184 * not Supported in case of concurrency i.e Once P2P session
8185 * is detected disable offchannel and teardown TDLS links
8186 */
8187 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
8188
Jeff Johnson295189b2012-06-20 16:38:30 -07008189 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008190 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07008191 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008192 )
8193 {
8194 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008195 if (!pWextState)
8196 {
8197 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8198 "%s: pWextState is null", __func__);
8199 return VOS_STATUS_E_FAILURE;
8200 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008201 pRoamProfile = &pWextState->roamProfile;
8202 LastBSSType = pRoamProfile->BSSType;
8203
8204 switch (type)
8205 {
8206 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008207 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008208 hddLog(VOS_TRACE_LEVEL_INFO,
8209 "%s: setting interface Type to INFRASTRUCTURE", __func__);
8210 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008211#ifdef WLAN_FEATURE_11AC
8212 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
8213 {
8214 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
8215 }
8216#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308217 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07008218 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008219 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008220 //Check for sub-string p2p to confirm its a p2p interface
8221 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308222 {
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008223 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8224 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8225 }
8226 else
8227 {
8228 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008229 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008230 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008231 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05308232
Jeff Johnson295189b2012-06-20 16:38:30 -07008233 case NL80211_IFTYPE_ADHOC:
8234 hddLog(VOS_TRACE_LEVEL_INFO,
8235 "%s: setting interface Type to ADHOC", __func__);
8236 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
8237 pRoamProfile->phyMode =
8238 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07008239 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008240 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +05308241 hdd_set_ibss_ops( pAdapter );
8242 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +05308243
8244 status = hdd_sta_id_hash_attach(pAdapter);
8245 if (VOS_STATUS_SUCCESS != status) {
8246 hddLog(VOS_TRACE_LEVEL_ERROR,
8247 FL("Failed to initialize hash for IBSS"));
8248 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008249 break;
8250
8251 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008252 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008253 {
8254 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8255 "%s: setting interface Type to %s", __func__,
8256 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
8257
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008258 //Cancel any remain on channel for GO mode
8259 if (NL80211_IFTYPE_P2P_GO == type)
8260 {
8261 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
8262 }
Mohit Khanna0f232092012-09-11 14:46:08 -07008263 if (NL80211_IFTYPE_AP == type)
8264 {
8265 /* As Loading WLAN Driver one interface being created for p2p device
8266 * address. This will take one HW STA and the max number of clients
8267 * that can connect to softAP will be reduced by one. so while changing
8268 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
8269 * interface as it is not required in SoftAP mode.
8270 */
8271
8272 // Get P2P Adapter
8273 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
8274
8275 if (pP2pAdapter)
8276 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308277 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05308278 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07008279 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
8280 }
8281 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05308282 //Disable IMPS & BMPS for SAP/GO
8283 if(VOS_STATUS_E_FAILURE ==
8284 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
8285 {
8286 //Fail to Exit BMPS
8287 VOS_ASSERT(0);
8288 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05308289
8290 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
8291
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308292#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07008293
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308294 /* A Mutex Lock is introduced while changing the mode to
8295 * protect the concurrent access for the Adapters by TDLS
8296 * module.
8297 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308298 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308299#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008300 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05308301 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008302 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07008303 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8304 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308305#ifdef FEATURE_WLAN_TDLS
8306 mutex_unlock(&pHddCtx->tdls_lock);
8307#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008308 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
8309 (pConfig->apRandomBssidEnabled))
8310 {
8311 /* To meet Android requirements create a randomized
8312 MAC address of the form 02:1A:11:Fx:xx:xx */
8313 get_random_bytes(&ndev->dev_addr[3], 3);
8314 ndev->dev_addr[0] = 0x02;
8315 ndev->dev_addr[1] = 0x1A;
8316 ndev->dev_addr[2] = 0x11;
8317 ndev->dev_addr[3] |= 0xF0;
8318 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
8319 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08008320 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
8321 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008322 }
8323
Jeff Johnson295189b2012-06-20 16:38:30 -07008324 hdd_set_ap_ops( pAdapter->dev );
8325
Kiet Lam10841362013-11-01 11:36:50 +05308326 /* This is for only SAP mode where users can
8327 * control country through ini.
8328 * P2P GO follows station country code
8329 * acquired during the STA scanning. */
8330 if((NL80211_IFTYPE_AP == type) &&
8331 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
8332 {
8333 int status = 0;
8334 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
8335 "%s: setting country code from INI ", __func__);
8336 init_completion(&pAdapter->change_country_code);
8337 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
8338 (void *)(tSmeChangeCountryCallback)
8339 wlan_hdd_change_country_code_cb,
8340 pConfig->apCntryCode, pAdapter,
8341 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308342 eSIR_FALSE,
8343 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05308344 if (eHAL_STATUS_SUCCESS == status)
8345 {
8346 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308347 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05308348 &pAdapter->change_country_code,
8349 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308350 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05308351 {
8352 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308353 FL("SME Timed out while setting country code %ld"),
8354 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08008355
8356 if (pHddCtx->isLogpInProgress)
8357 {
8358 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8359 "%s: LOGP in Progress. Ignore!!!", __func__);
8360 return -EAGAIN;
8361 }
Kiet Lam10841362013-11-01 11:36:50 +05308362 }
8363 }
8364 else
8365 {
8366 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008367 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05308368 return -EINVAL;
8369 }
8370 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008371 status = hdd_init_ap_mode(pAdapter);
8372 if(status != VOS_STATUS_SUCCESS)
8373 {
8374 hddLog(VOS_TRACE_LEVEL_FATAL,
8375 "%s: Error initializing the ap mode", __func__);
8376 return -EINVAL;
8377 }
8378 hdd_set_conparam(1);
8379
Nirav Shah7e3c8132015-06-22 23:51:42 +05308380 status = hdd_sta_id_hash_attach(pAdapter);
8381 if (VOS_STATUS_SUCCESS != status)
8382 {
8383 hddLog(VOS_TRACE_LEVEL_ERROR,
8384 FL("Failed to initialize hash for AP"));
8385 return -EINVAL;
8386 }
8387
Jeff Johnson295189b2012-06-20 16:38:30 -07008388 /*interface type changed update in wiphy structure*/
8389 if(wdev)
8390 {
8391 wdev->iftype = type;
8392 pHddCtx->change_iface = type;
8393 }
8394 else
8395 {
8396 hddLog(VOS_TRACE_LEVEL_ERROR,
8397 "%s: ERROR !!!! Wireless dev is NULL", __func__);
8398 return -EINVAL;
8399 }
8400 goto done;
8401 }
8402
8403 default:
8404 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8405 __func__);
8406 return -EOPNOTSUPP;
8407 }
8408 }
8409 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008410 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008411 )
8412 {
8413 switch(type)
8414 {
8415 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008416 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008417 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05308418
8419 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308420#ifdef FEATURE_WLAN_TDLS
8421
8422 /* A Mutex Lock is introduced while changing the mode to
8423 * protect the concurrent access for the Adapters by TDLS
8424 * module.
8425 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308426 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308427#endif
c_hpothu002231a2015-02-05 14:58:51 +05308428 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008429 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008430 //Check for sub-string p2p to confirm its a p2p interface
8431 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008432 {
8433 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8434 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8435 }
8436 else
8437 {
8438 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008439 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008440 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008441 hdd_set_conparam(0);
8442 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008443 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
8444 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308445#ifdef FEATURE_WLAN_TDLS
8446 mutex_unlock(&pHddCtx->tdls_lock);
8447#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308448 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008449 if( VOS_STATUS_SUCCESS != status )
8450 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07008451 /* In case of JB, for P2P-GO, only change interface will be called,
8452 * This is the right place to enable back bmps_imps()
8453 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308454 if (pHddCtx->hdd_wlan_suspended)
8455 {
8456 hdd_set_pwrparams(pHddCtx);
8457 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008458 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008459 goto done;
8460 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008461 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008462 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008463 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8464 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008465 goto done;
8466 default:
8467 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8468 __func__);
8469 return -EOPNOTSUPP;
8470
8471 }
8472
8473 }
8474 else
8475 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308476 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
8477 __func__, hdd_device_modetoString(pAdapter->device_mode),
8478 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008479 return -EOPNOTSUPP;
8480 }
8481
8482
8483 if(pRoamProfile)
8484 {
8485 if ( LastBSSType != pRoamProfile->BSSType )
8486 {
8487 /*interface type changed update in wiphy structure*/
8488 wdev->iftype = type;
8489
8490 /*the BSS mode changed, We need to issue disconnect
8491 if connected or in IBSS disconnect state*/
8492 if ( hdd_connGetConnectedBssType(
8493 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
8494 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
8495 {
8496 /*need to issue a disconnect to CSR.*/
8497 INIT_COMPLETION(pAdapter->disconnect_comp_var);
8498 if( eHAL_STATUS_SUCCESS ==
8499 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
8500 pAdapter->sessionId,
8501 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
8502 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308503 ret = wait_for_completion_interruptible_timeout(
8504 &pAdapter->disconnect_comp_var,
8505 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
8506 if (ret <= 0)
8507 {
8508 hddLog(VOS_TRACE_LEVEL_ERROR,
8509 FL("wait on disconnect_comp_var failed %ld"), ret);
8510 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008511 }
8512 }
8513 }
8514 }
8515
8516done:
8517 /*set bitmask based on updated value*/
8518 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07008519
8520 /* Only STA mode support TM now
8521 * all other mode, TM feature should be disabled */
8522 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
8523 (~VOS_STA & pHddCtx->concurrency_mode) )
8524 {
8525 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
8526 }
8527
Jeff Johnson295189b2012-06-20 16:38:30 -07008528#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308529 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05308530 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07008531 {
8532 //we are ok to do AMP
8533 pHddCtx->isAmpAllowed = VOS_TRUE;
8534 }
8535#endif //WLAN_BTAMP_FEATURE
8536 EXIT();
8537 return 0;
8538}
8539
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308540/*
8541 * FUNCTION: wlan_hdd_cfg80211_change_iface
8542 * wrapper function to protect the actual implementation from SSR.
8543 */
8544int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
8545 struct net_device *ndev,
8546 enum nl80211_iftype type,
8547 u32 *flags,
8548 struct vif_params *params
8549 )
8550{
8551 int ret;
8552
8553 vos_ssr_protect(__func__);
8554 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
8555 vos_ssr_unprotect(__func__);
8556
8557 return ret;
8558}
8559
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008560#ifdef FEATURE_WLAN_TDLS
8561static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308562 struct net_device *dev,
8563#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
8564 const u8 *mac,
8565#else
8566 u8 *mac,
8567#endif
8568 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008569{
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008570 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008571 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308572 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308573 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308574 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05308575 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008576
8577 ENTER();
8578
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308579 if (!dev) {
8580 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
8581 return -EINVAL;
8582 }
8583
8584 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8585 if (!pAdapter) {
8586 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
8587 return -EINVAL;
8588 }
8589
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308590 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008591 {
8592 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8593 "Invalid arguments");
8594 return -EINVAL;
8595 }
Hoonki Lee27511902013-03-14 18:19:06 -07008596
8597 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
8598 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
8599 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308600 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -07008601 "%s: TDLS mode is disabled OR not enabled in FW."
8602 MAC_ADDRESS_STR " Request declined.",
8603 __func__, MAC_ADDR_ARRAY(mac));
8604 return -ENOTSUPP;
8605 }
8606
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008607 if (pHddCtx->isLogpInProgress)
8608 {
8609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8610 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05308611 wlan_hdd_tdls_set_link_status(pAdapter,
8612 mac,
8613 eTDLS_LINK_IDLE,
8614 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008615 return -EBUSY;
8616 }
8617
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308618 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05308619 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008620
8621 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308622 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008623 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
8624 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308625 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008626 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008627 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308628 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008629
8630 /* in add station, we accept existing valid staId if there is */
8631 if ((0 == update) &&
8632 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
8633 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008634 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008636 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008637 " link_status %d. staId %d. add station ignored.",
8638 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
8639 return 0;
8640 }
8641 /* in change station, we accept only when staId is valid */
8642 if ((1 == update) &&
8643 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
8644 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
8645 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308646 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008647 "%s: " MAC_ADDRESS_STR
8648 " link status %d. staId %d. change station %s.",
8649 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
8650 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
8651 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008652 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008653
8654 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +05308655 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008656 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008657 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8658 "%s: " MAC_ADDRESS_STR
8659 " TDLS setup is ongoing. Request declined.",
8660 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07008661 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008662 }
8663
8664 /* first to check if we reached to maximum supported TDLS peer.
8665 TODO: for now, return -EPERM looks working fine,
8666 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308667 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8668 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008669 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008670 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8671 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308672 " TDLS Max peer already connected. Request declined."
8673 " Num of peers (%d), Max allowed (%d).",
8674 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
8675 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008676 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008677 }
8678 else
8679 {
8680 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308681 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008682 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008683 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008684 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8685 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
8686 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008687 return -EPERM;
8688 }
8689 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008690 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05308691 wlan_hdd_tdls_set_link_status(pAdapter,
8692 mac,
8693 eTDLS_LINK_CONNECTING,
8694 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008695
Jeff Johnsond75fe012013-04-06 10:53:06 -07008696 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308697 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008698 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308699 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008700 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008701 if(StaParams->htcap_present)
8702 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308703 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008704 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308705 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008706 "ht_capa->extended_capabilities: %0x",
8707 StaParams->HTCap.extendedHtCapInfo);
8708 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308709 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008710 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308711 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008712 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008713 if(StaParams->vhtcap_present)
8714 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308715 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008716 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
8717 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
8718 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
8719 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008720 {
8721 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008722 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008723 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008725 "[%d]: %x ", i, StaParams->supported_rates[i]);
8726 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07008727 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308728 else if ((1 == update) && (NULL == StaParams))
8729 {
8730 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8731 "%s : update is true, but staParams is NULL. Error!", __func__);
8732 return -EPERM;
8733 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008734
8735 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
8736
8737 if (!update)
8738 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05308739 /*Before adding sta make sure that device exited from BMPS*/
8740 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
8741 {
8742 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8743 "%s: Adding tdls peer sta. Disable BMPS", __func__);
8744 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
8745 if (status != VOS_STATUS_SUCCESS) {
8746 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
8747 }
8748 }
8749
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308750 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008751 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308752 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05308753 hddLog(VOS_TRACE_LEVEL_ERROR,
8754 FL("Failed to add TDLS peer STA. Enable Bmps"));
8755 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308756 return -EPERM;
8757 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008758 }
8759 else
8760 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308761 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008762 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308763 if (ret != eHAL_STATUS_SUCCESS) {
8764 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
8765 return -EPERM;
8766 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008767 }
8768
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308769 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008770 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
8771
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308772 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008773 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008774 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308775 "%s: timeout waiting for tdls add station indication %ld",
8776 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008777 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008778 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308779
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008780 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
8781 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008782 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008783 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008784 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008785 }
8786
8787 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008788
8789error:
Atul Mittal115287b2014-07-08 13:26:33 +05308790 wlan_hdd_tdls_set_link_status(pAdapter,
8791 mac,
8792 eTDLS_LINK_IDLE,
8793 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008794 return -EPERM;
8795
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008796}
8797#endif
8798
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308799static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008800 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308801#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
8802 const u8 *mac,
8803#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008804 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308805#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008806 struct station_parameters *params)
8807{
8808 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308809 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308810 hdd_context_t *pHddCtx;
8811 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008812 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308813 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008814#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008815 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008816 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308817 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008818#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008819
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308820 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308821
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308822 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308823 if ((NULL == pAdapter))
8824 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308825 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308826 "invalid adapter ");
8827 return -EINVAL;
8828 }
8829
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308830 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8831 TRACE_CODE_HDD_CHANGE_STATION,
8832 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05308833 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308834
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308835 ret = wlan_hdd_validate_context(pHddCtx);
8836 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05308837 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308838 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308839 }
8840
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308841 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8842
8843 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008844 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308845 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8846 "invalid HDD station context");
8847 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008848 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008849 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
8850
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008851 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
8852 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07008853 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008854 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07008855 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308856 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07008857 WLANTL_STA_AUTHENTICATED);
8858
Gopichand Nakkala29149562013-05-10 21:43:41 +05308859 if (status != VOS_STATUS_SUCCESS)
8860 {
8861 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8862 "%s: Not able to change TL state to AUTHENTICATED", __func__);
8863 return -EINVAL;
8864 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008865 }
8866 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07008867 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8868 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308869#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008870 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8871 StaParams.capability = params->capability;
8872 StaParams.uapsd_queues = params->uapsd_queues;
8873 StaParams.max_sp = params->max_sp;
8874
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308875 /* Convert (first channel , number of channels) tuple to
8876 * the total list of channels. This goes with the assumption
8877 * that if the first channel is < 14, then the next channels
8878 * are an incremental of 1 else an incremental of 4 till the number
8879 * of channels.
8880 */
8881 if (0 != params->supported_channels_len) {
8882 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
8883 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
8884 {
8885 int wifi_chan_index;
8886 StaParams.supported_channels[j] = params->supported_channels[i];
8887 wifi_chan_index =
8888 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
8889 no_of_channels = params->supported_channels[i+1];
8890 for(k=1; k <= no_of_channels; k++)
8891 {
8892 StaParams.supported_channels[j+1] =
8893 StaParams.supported_channels[j] + wifi_chan_index;
8894 j+=1;
8895 }
8896 }
8897 StaParams.supported_channels_len = j;
8898 }
8899 vos_mem_copy(StaParams.supported_oper_classes,
8900 params->supported_oper_classes,
8901 params->supported_oper_classes_len);
8902 StaParams.supported_oper_classes_len =
8903 params->supported_oper_classes_len;
8904
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008905 if (0 != params->ext_capab_len)
8906 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
8907 sizeof(StaParams.extn_capability));
8908
8909 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008910 {
8911 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008912 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008913 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008914
8915 StaParams.supported_rates_len = params->supported_rates_len;
8916
8917 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
8918 * The supported_rates array , for all the structures propogating till Add Sta
8919 * to the firmware has to be modified , if the supplicant (ieee80211) is
8920 * modified to send more rates.
8921 */
8922
8923 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
8924 */
8925 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
8926 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
8927
8928 if (0 != StaParams.supported_rates_len) {
8929 int i = 0;
8930 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
8931 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008932 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008933 "Supported Rates with Length %d", StaParams.supported_rates_len);
8934 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008935 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008936 "[%d]: %0x", i, StaParams.supported_rates[i]);
8937 }
8938
8939 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008940 {
8941 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008942 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008943 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008944
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008945 if (0 != params->ext_capab_len ) {
8946 /*Define A Macro : TODO Sunil*/
8947 if ((1<<4) & StaParams.extn_capability[3]) {
8948 isBufSta = 1;
8949 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308950 /* TDLS Channel Switching Support */
8951 if ((1<<6) & StaParams.extn_capability[3]) {
8952 isOffChannelSupported = 1;
8953 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008954 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308955 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
8956 &StaParams, isBufSta,
8957 isOffChannelSupported);
8958
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308959 if (VOS_STATUS_SUCCESS != status) {
8960 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8961 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
8962 return -EINVAL;
8963 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008964 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
8965
8966 if (VOS_STATUS_SUCCESS != status) {
8967 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8968 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
8969 return -EINVAL;
8970 }
8971 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008972#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05308973 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008974 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008975 return status;
8976}
8977
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308978#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
8979static int wlan_hdd_change_station(struct wiphy *wiphy,
8980 struct net_device *dev,
8981 const u8 *mac,
8982 struct station_parameters *params)
8983#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308984static int wlan_hdd_change_station(struct wiphy *wiphy,
8985 struct net_device *dev,
8986 u8 *mac,
8987 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308988#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308989{
8990 int ret;
8991
8992 vos_ssr_protect(__func__);
8993 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
8994 vos_ssr_unprotect(__func__);
8995
8996 return ret;
8997}
8998
Jeff Johnson295189b2012-06-20 16:38:30 -07008999/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309000 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009001 * This function is used to initialize the key information
9002 */
9003#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309004static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009005 struct net_device *ndev,
9006 u8 key_index, bool pairwise,
9007 const u8 *mac_addr,
9008 struct key_params *params
9009 )
9010#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309011static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009012 struct net_device *ndev,
9013 u8 key_index, const u8 *mac_addr,
9014 struct key_params *params
9015 )
9016#endif
9017{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009018 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07009019 tCsrRoamSetKey setKey;
9020 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309021 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009022 v_U32_t roamId= 0xFF;
9023 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009024 hdd_hostapd_state_t *pHostapdState;
9025 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009026 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309027 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009028
9029 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309030
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309031 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9032 TRACE_CODE_HDD_CFG80211_ADD_KEY,
9033 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309034 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9035 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309036 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009037 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309038 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009039 }
9040
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309041 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9042 __func__, hdd_device_modetoString(pAdapter->device_mode),
9043 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009044
9045 if (CSR_MAX_NUM_KEY <= key_index)
9046 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009047 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009048 key_index);
9049
9050 return -EINVAL;
9051 }
9052
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009053 if (CSR_MAX_KEY_LEN < params->key_len)
9054 {
9055 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
9056 params->key_len);
9057
9058 return -EINVAL;
9059 }
9060
9061 hddLog(VOS_TRACE_LEVEL_INFO,
9062 "%s: called with key index = %d & key length %d",
9063 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009064
9065 /*extract key idx, key len and key*/
9066 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9067 setKey.keyId = key_index;
9068 setKey.keyLength = params->key_len;
9069 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
9070
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009071 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009072 {
9073 case WLAN_CIPHER_SUITE_WEP40:
9074 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
9075 break;
9076
9077 case WLAN_CIPHER_SUITE_WEP104:
9078 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
9079 break;
9080
9081 case WLAN_CIPHER_SUITE_TKIP:
9082 {
9083 u8 *pKey = &setKey.Key[0];
9084 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
9085
9086 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
9087
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009088 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07009089
9090 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009091 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009092 |--------------|----------|----------|
9093 <---16bytes---><--8bytes--><--8bytes-->
9094
9095 */
9096 /*Sme expects the 32 bytes key to be in the below order
9097
9098 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009099 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009100 |--------------|----------|----------|
9101 <---16bytes---><--8bytes--><--8bytes-->
9102 */
9103 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009104 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07009105
9106 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009107 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009108
9109 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009110 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009111
9112
9113 break;
9114 }
9115
9116 case WLAN_CIPHER_SUITE_CCMP:
9117 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
9118 break;
9119
9120#ifdef FEATURE_WLAN_WAPI
9121 case WLAN_CIPHER_SUITE_SMS4:
9122 {
9123 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9124 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
9125 params->key, params->key_len);
9126 return 0;
9127 }
9128#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009129
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009130#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009131 case WLAN_CIPHER_SUITE_KRK:
9132 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
9133 break;
9134#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009135
9136#ifdef WLAN_FEATURE_11W
9137 case WLAN_CIPHER_SUITE_AES_CMAC:
9138 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07009139 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07009140#endif
9141
Jeff Johnson295189b2012-06-20 16:38:30 -07009142 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009143 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009144 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309145 status = -EOPNOTSUPP;
9146 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009147 }
9148
9149 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
9150 __func__, setKey.encType);
9151
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009152 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07009153#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9154 (!pairwise)
9155#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009156 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07009157#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009158 )
9159 {
9160 /* set group key*/
9161 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9162 "%s- %d: setting Broadcast key",
9163 __func__, __LINE__);
9164 setKey.keyDirection = eSIR_RX_ONLY;
9165 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9166 }
9167 else
9168 {
9169 /* set pairwise key*/
9170 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9171 "%s- %d: setting pairwise key",
9172 __func__, __LINE__);
9173 setKey.keyDirection = eSIR_TX_RX;
9174 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9175 }
9176 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
9177 {
9178 setKey.keyDirection = eSIR_TX_RX;
9179 /*Set the group key*/
9180 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9181 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07009182
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009183 if ( 0 != status )
9184 {
9185 hddLog(VOS_TRACE_LEVEL_ERROR,
9186 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309187 status = -EINVAL;
9188 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009189 }
9190 /*Save the keys here and call sme_RoamSetKey for setting
9191 the PTK after peer joins the IBSS network*/
9192 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
9193 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309194 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009195 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05309196 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
9197 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
9198 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009199 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009200 if( pHostapdState->bssState == BSS_START )
9201 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009202 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9203 vos_status = wlan_hdd_check_ula_done(pAdapter);
9204
9205 if ( vos_status != VOS_STATUS_SUCCESS )
9206 {
9207 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9208 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9209 __LINE__, vos_status );
9210
9211 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9212
9213 status = -EINVAL;
9214 goto end;
9215 }
9216
Jeff Johnson295189b2012-06-20 16:38:30 -07009217 status = WLANSAP_SetKeySta( pVosContext, &setKey);
9218
9219 if ( status != eHAL_STATUS_SUCCESS )
9220 {
9221 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9222 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9223 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309224 status = -EINVAL;
9225 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009226 }
9227 }
9228
9229 /* Saving WEP keys */
9230 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
9231 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
9232 {
9233 //Save the wep key in ap context. Issue setkey after the BSS is started.
9234 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9235 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
9236 }
9237 else
9238 {
9239 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009240 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009241 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
9242 }
9243 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009244 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
9245 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009246 {
9247 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9248 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9249
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309250#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9251 if (!pairwise)
9252#else
9253 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9254#endif
9255 {
9256 /* set group key*/
9257 if (pHddStaCtx->roam_info.deferKeyComplete)
9258 {
9259 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9260 "%s- %d: Perform Set key Complete",
9261 __func__, __LINE__);
9262 hdd_PerformRoamSetKeyComplete(pAdapter);
9263 }
9264 }
9265
Jeff Johnson295189b2012-06-20 16:38:30 -07009266 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
9267
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08009268 pWextState->roamProfile.Keys.defaultIndex = key_index;
9269
9270
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009271 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009272 params->key, params->key_len);
9273
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309274
Jeff Johnson295189b2012-06-20 16:38:30 -07009275 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9276
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309277 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009278 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309279 __func__, setKey.peerMac[0], setKey.peerMac[1],
9280 setKey.peerMac[2], setKey.peerMac[3],
9281 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009282 setKey.keyDirection);
9283
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009284 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +05309285
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009286 if ( vos_status != VOS_STATUS_SUCCESS )
9287 {
9288 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009289 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9290 __LINE__, vos_status );
9291
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009292 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009293
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009294 status = -EINVAL;
9295 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009296
9297 }
9298
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009299#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309300 /* The supplicant may attempt to set the PTK once pre-authentication
9301 is done. Save the key in the UMAC and include it in the ADD BSS
9302 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009303 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309304 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009305 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309306 hddLog(VOS_TRACE_LEVEL_INFO_MED,
9307 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309308 status = 0;
9309 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309310 }
9311 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
9312 {
9313 hddLog(VOS_TRACE_LEVEL_ERROR,
9314 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309315 status = -EINVAL;
9316 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009317 }
9318#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07009319
9320 /* issue set key request to SME*/
9321 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9322 pAdapter->sessionId, &setKey, &roamId );
9323
9324 if ( 0 != status )
9325 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309326 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009327 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
9328 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309329 status = -EINVAL;
9330 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009331 }
9332
9333
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309334 /* in case of IBSS as there was no information available about WEP keys during
9335 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07009336 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309337 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
9338 !( ( IW_AUTH_KEY_MGMT_802_1X
9339 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07009340 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
9341 )
9342 &&
9343 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
9344 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
9345 )
9346 )
9347 {
9348 setKey.keyDirection = eSIR_RX_ONLY;
9349 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9350
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309351 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009352 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309353 __func__, setKey.peerMac[0], setKey.peerMac[1],
9354 setKey.peerMac[2], setKey.peerMac[3],
9355 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009356 setKey.keyDirection);
9357
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309358 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009359 pAdapter->sessionId, &setKey, &roamId );
9360
9361 if ( 0 != status )
9362 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309363 hddLog(VOS_TRACE_LEVEL_ERROR,
9364 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009365 __func__, status);
9366 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309367 status = -EINVAL;
9368 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009369 }
9370 }
9371 }
9372
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309373end:
9374 /* Need to clear any trace of key value in the memory.
9375 * Thus zero out the memory even though it is local
9376 * variable.
9377 */
9378 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309379 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309380 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009381}
9382
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309383#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9384static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9385 struct net_device *ndev,
9386 u8 key_index, bool pairwise,
9387 const u8 *mac_addr,
9388 struct key_params *params
9389 )
9390#else
9391static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9392 struct net_device *ndev,
9393 u8 key_index, const u8 *mac_addr,
9394 struct key_params *params
9395 )
9396#endif
9397{
9398 int ret;
9399 vos_ssr_protect(__func__);
9400#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9401 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
9402 mac_addr, params);
9403#else
9404 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
9405 params);
9406#endif
9407 vos_ssr_unprotect(__func__);
9408
9409 return ret;
9410}
9411
Jeff Johnson295189b2012-06-20 16:38:30 -07009412/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309413 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009414 * This function is used to get the key information
9415 */
9416#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309417static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309418 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009419 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309420 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009421 const u8 *mac_addr, void *cookie,
9422 void (*callback)(void *cookie, struct key_params*)
9423 )
9424#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309425static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309426 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009427 struct net_device *ndev,
9428 u8 key_index, const u8 *mac_addr, void *cookie,
9429 void (*callback)(void *cookie, struct key_params*)
9430 )
9431#endif
9432{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309433 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309434 hdd_wext_state_t *pWextState = NULL;
9435 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009436 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309437 hdd_context_t *pHddCtx;
9438 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009439
9440 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309441
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309442 if (NULL == pAdapter)
9443 {
9444 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9445 "%s: HDD adapter is Null", __func__);
9446 return -ENODEV;
9447 }
9448
9449 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9450 ret = wlan_hdd_validate_context(pHddCtx);
9451 if (0 != ret)
9452 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309453 return ret;
9454 }
9455
9456 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9457 pRoamProfile = &(pWextState->roamProfile);
9458
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309459 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9460 __func__, hdd_device_modetoString(pAdapter->device_mode),
9461 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309462
Jeff Johnson295189b2012-06-20 16:38:30 -07009463 memset(&params, 0, sizeof(params));
9464
9465 if (CSR_MAX_NUM_KEY <= key_index)
9466 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309467 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07009468 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309469 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009470
9471 switch(pRoamProfile->EncryptionType.encryptionType[0])
9472 {
9473 case eCSR_ENCRYPT_TYPE_NONE:
9474 params.cipher = IW_AUTH_CIPHER_NONE;
9475 break;
9476
9477 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
9478 case eCSR_ENCRYPT_TYPE_WEP40:
9479 params.cipher = WLAN_CIPHER_SUITE_WEP40;
9480 break;
9481
9482 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
9483 case eCSR_ENCRYPT_TYPE_WEP104:
9484 params.cipher = WLAN_CIPHER_SUITE_WEP104;
9485 break;
9486
9487 case eCSR_ENCRYPT_TYPE_TKIP:
9488 params.cipher = WLAN_CIPHER_SUITE_TKIP;
9489 break;
9490
9491 case eCSR_ENCRYPT_TYPE_AES:
9492 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
9493 break;
9494
9495 default:
9496 params.cipher = IW_AUTH_CIPHER_NONE;
9497 break;
9498 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309499
c_hpothuaaf19692014-05-17 17:01:48 +05309500 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9501 TRACE_CODE_HDD_CFG80211_GET_KEY,
9502 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309503
Jeff Johnson295189b2012-06-20 16:38:30 -07009504 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
9505 params.seq_len = 0;
9506 params.seq = NULL;
9507 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
9508 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309509 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009510 return 0;
9511}
9512
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309513#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9514static int wlan_hdd_cfg80211_get_key(
9515 struct wiphy *wiphy,
9516 struct net_device *ndev,
9517 u8 key_index, bool pairwise,
9518 const u8 *mac_addr, void *cookie,
9519 void (*callback)(void *cookie, struct key_params*)
9520 )
9521#else
9522static int wlan_hdd_cfg80211_get_key(
9523 struct wiphy *wiphy,
9524 struct net_device *ndev,
9525 u8 key_index, const u8 *mac_addr, void *cookie,
9526 void (*callback)(void *cookie, struct key_params*)
9527 )
9528#endif
9529{
9530 int ret;
9531
9532 vos_ssr_protect(__func__);
9533#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9534 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
9535 mac_addr, cookie, callback);
9536#else
9537 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
9538 callback);
9539#endif
9540 vos_ssr_unprotect(__func__);
9541
9542 return ret;
9543}
9544
Jeff Johnson295189b2012-06-20 16:38:30 -07009545/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309546 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009547 * This function is used to delete the key information
9548 */
9549#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309550static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009551 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309552 u8 key_index,
9553 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009554 const u8 *mac_addr
9555 )
9556#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309557static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009558 struct net_device *ndev,
9559 u8 key_index,
9560 const u8 *mac_addr
9561 )
9562#endif
9563{
9564 int status = 0;
9565
9566 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309567 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07009568 //it is observed that this is invalidating peer
9569 //key index whenever re-key is done. This is affecting data link.
9570 //It should be ok to ignore del_key.
9571#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309572 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
9573 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009574 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
9575 tCsrRoamSetKey setKey;
9576 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309577
Jeff Johnson295189b2012-06-20 16:38:30 -07009578 ENTER();
9579
9580 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
9581 __func__,pAdapter->device_mode);
9582
9583 if (CSR_MAX_NUM_KEY <= key_index)
9584 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309585 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009586 key_index);
9587
9588 return -EINVAL;
9589 }
9590
9591 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9592 setKey.keyId = key_index;
9593
9594 if (mac_addr)
9595 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9596 else
9597 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
9598
9599 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
9600
9601 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009602 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309603 )
9604 {
9605
9606 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07009607 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9608 if( pHostapdState->bssState == BSS_START)
9609 {
9610 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309611
Jeff Johnson295189b2012-06-20 16:38:30 -07009612 if ( status != eHAL_STATUS_SUCCESS )
9613 {
9614 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9615 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9616 __LINE__, status );
9617 }
9618 }
9619 }
9620 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309621 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07009622 )
9623 {
9624 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9625
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309626 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9627
9628 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009629 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309630 __func__, setKey.peerMac[0], setKey.peerMac[1],
9631 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07009632 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309633 if(pAdapter->sessionCtx.station.conn_info.connState ==
9634 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07009635 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309636 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009637 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309638
Jeff Johnson295189b2012-06-20 16:38:30 -07009639 if ( 0 != status )
9640 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309641 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009642 "%s: sme_RoamSetKey failure, returned %d",
9643 __func__, status);
9644 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9645 return -EINVAL;
9646 }
9647 }
9648 }
9649#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009650 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009651 return status;
9652}
9653
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309654#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9655static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9656 struct net_device *ndev,
9657 u8 key_index,
9658 bool pairwise,
9659 const u8 *mac_addr
9660 )
9661#else
9662static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9663 struct net_device *ndev,
9664 u8 key_index,
9665 const u8 *mac_addr
9666 )
9667#endif
9668{
9669 int ret;
9670
9671 vos_ssr_protect(__func__);
9672#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9673 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
9674 mac_addr);
9675#else
9676 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
9677#endif
9678 vos_ssr_unprotect(__func__);
9679
9680 return ret;
9681}
9682
Jeff Johnson295189b2012-06-20 16:38:30 -07009683/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309684 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009685 * This function is used to set the default tx key index
9686 */
9687#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309688static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009689 struct net_device *ndev,
9690 u8 key_index,
9691 bool unicast, bool multicast)
9692#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309693static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009694 struct net_device *ndev,
9695 u8 key_index)
9696#endif
9697{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309698 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309699 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309700 hdd_wext_state_t *pWextState;
9701 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309702 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009703
9704 ENTER();
9705
Gopichand Nakkala29149562013-05-10 21:43:41 +05309706 if ((NULL == pAdapter))
9707 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309708 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309709 "invalid adapter");
9710 return -EINVAL;
9711 }
9712
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309713 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9714 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
9715 pAdapter->sessionId, key_index));
9716
Gopichand Nakkala29149562013-05-10 21:43:41 +05309717 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9718 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9719
9720 if ((NULL == pWextState) || (NULL == pHddStaCtx))
9721 {
9722 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9723 "invalid Wext state or HDD context");
9724 return -EINVAL;
9725 }
9726
Arif Hussain6d2a3322013-11-17 19:50:10 -08009727 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009728 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309729
Jeff Johnson295189b2012-06-20 16:38:30 -07009730 if (CSR_MAX_NUM_KEY <= key_index)
9731 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309732 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009733 key_index);
9734
9735 return -EINVAL;
9736 }
9737
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309738 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9739 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309740 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009741 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309742 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009743 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309744
Jeff Johnson295189b2012-06-20 16:38:30 -07009745 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07009746 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309747 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009748 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309749 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08009750 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309751 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08009752 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07009753 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309754 {
9755 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07009756 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309757
Jeff Johnson295189b2012-06-20 16:38:30 -07009758 tCsrRoamSetKey setKey;
9759 v_U32_t roamId= 0xFF;
9760 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309761
9762 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009763 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309764
Jeff Johnson295189b2012-06-20 16:38:30 -07009765 Keys->defaultIndex = (u8)key_index;
9766 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9767 setKey.keyId = key_index;
9768 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309769
9770 vos_mem_copy(&setKey.Key[0],
9771 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009772 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309773
Gopichand Nakkala29149562013-05-10 21:43:41 +05309774 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309775
9776 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07009777 &pHddStaCtx->conn_info.bssId[0],
9778 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309779
Gopichand Nakkala29149562013-05-10 21:43:41 +05309780 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
9781 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
9782 eCSR_ENCRYPT_TYPE_WEP104)
9783 {
9784 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
9785 even though ap is configured for WEP-40 encryption. In this canse the key length
9786 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
9787 type(104) and switching encryption type to 40*/
9788 pWextState->roamProfile.EncryptionType.encryptionType[0] =
9789 eCSR_ENCRYPT_TYPE_WEP40;
9790 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
9791 eCSR_ENCRYPT_TYPE_WEP40;
9792 }
9793
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309794 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07009795 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309796
Jeff Johnson295189b2012-06-20 16:38:30 -07009797 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309798 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009799 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309800
Jeff Johnson295189b2012-06-20 16:38:30 -07009801 if ( 0 != status )
9802 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309803 hddLog(VOS_TRACE_LEVEL_ERROR,
9804 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009805 status);
9806 return -EINVAL;
9807 }
9808 }
9809 }
9810
9811 /* In SoftAp mode setting key direction for default mode */
9812 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
9813 {
9814 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
9815 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
9816 (eCSR_ENCRYPT_TYPE_AES !=
9817 pWextState->roamProfile.EncryptionType.encryptionType[0])
9818 )
9819 {
9820 /* Saving key direction for default key index to TX default */
9821 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9822 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
9823 }
9824 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309825 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009826 return status;
9827}
9828
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309829#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9830static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9831 struct net_device *ndev,
9832 u8 key_index,
9833 bool unicast, bool multicast)
9834#else
9835static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9836 struct net_device *ndev,
9837 u8 key_index)
9838#endif
9839{
9840 int ret;
9841 vos_ssr_protect(__func__);
9842#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9843 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
9844 multicast);
9845#else
9846 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
9847#endif
9848 vos_ssr_unprotect(__func__);
9849
9850 return ret;
9851}
9852
Jeff Johnson295189b2012-06-20 16:38:30 -07009853/*
9854 * FUNCTION: wlan_hdd_cfg80211_inform_bss
9855 * This function is used to inform the BSS details to nl80211 interface.
9856 */
9857static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
9858 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
9859{
9860 struct net_device *dev = pAdapter->dev;
9861 struct wireless_dev *wdev = dev->ieee80211_ptr;
9862 struct wiphy *wiphy = wdev->wiphy;
9863 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
9864 int chan_no;
9865 int ie_length;
9866 const char *ie;
9867 unsigned int freq;
9868 struct ieee80211_channel *chan;
9869 int rssi = 0;
9870 struct cfg80211_bss *bss = NULL;
9871
Jeff Johnson295189b2012-06-20 16:38:30 -07009872 if( NULL == pBssDesc )
9873 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009874 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009875 return bss;
9876 }
9877
9878 chan_no = pBssDesc->channelId;
9879 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
9880 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
9881
9882 if( NULL == ie )
9883 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009884 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009885 return bss;
9886 }
9887
9888#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9889 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9890 {
9891 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9892 }
9893 else
9894 {
9895 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9896 }
9897#else
9898 freq = ieee80211_channel_to_frequency(chan_no);
9899#endif
9900
9901 chan = __ieee80211_get_channel(wiphy, freq);
9902
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05309903 if (!chan) {
9904 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
9905 return NULL;
9906 }
9907
Abhishek Singhaee43942014-06-16 18:55:47 +05309908 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07009909
Anand N Sunkad9f80b742015-07-30 20:05:51 +05309910 return cfg80211_inform_bss(wiphy, chan,
9911#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
9912 CFG80211_BSS_FTYPE_UNKNOWN,
9913#endif
9914 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309915 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07009916 pBssDesc->capabilityInfo,
9917 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05309918 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07009919}
9920
9921
9922
9923/*
9924 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
9925 * This function is used to inform the BSS details to nl80211 interface.
9926 */
9927struct cfg80211_bss*
9928wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
9929 tSirBssDescription *bss_desc
9930 )
9931{
9932 /*
9933 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
9934 already exists in bss data base of cfg80211 for that particular BSS ID.
9935 Using cfg80211_inform_bss_frame to update the bss entry instead of
9936 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
9937 now there is no possibility to get the mgmt(probe response) frame from PE,
9938 converting bss_desc to ieee80211_mgmt(probe response) and passing to
9939 cfg80211_inform_bss_frame.
9940 */
9941 struct net_device *dev = pAdapter->dev;
9942 struct wireless_dev *wdev = dev->ieee80211_ptr;
9943 struct wiphy *wiphy = wdev->wiphy;
9944 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009945#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9946 qcom_ie_age *qie_age = NULL;
9947 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
9948#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009949 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009950#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009951 const char *ie =
9952 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
9953 unsigned int freq;
9954 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309955 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009956 struct cfg80211_bss *bss_status = NULL;
9957 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
9958 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07009959 hdd_context_t *pHddCtx;
9960 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07009961#ifdef WLAN_OPEN_SOURCE
9962 struct timespec ts;
9963#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009964
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309965
Wilson Yangf80a0542013-10-07 13:02:37 -07009966 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9967 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -07009968 if (0 != status)
9969 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009970 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009971 }
9972
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309973 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07009974 if (!mgmt)
9975 {
9976 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9977 "%s: memory allocation failed ", __func__);
9978 return NULL;
9979 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009980
Jeff Johnson295189b2012-06-20 16:38:30 -07009981 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -07009982
9983#ifdef WLAN_OPEN_SOURCE
9984 /* Android does not want the timestamp from the frame.
9985 Instead it wants a monotonic increasing value */
9986 get_monotonic_boottime(&ts);
9987 mgmt->u.probe_resp.timestamp =
9988 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
9989#else
9990 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -07009991 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
9992 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -07009993
9994#endif
9995
Jeff Johnson295189b2012-06-20 16:38:30 -07009996 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
9997 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009998
9999#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
10000 /* GPS Requirement: need age ie per entry. Using vendor specific. */
10001 /* Assuming this is the last IE, copy at the end */
10002 ie_length -=sizeof(qcom_ie_age);
10003 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
10004 qie_age->element_id = QCOM_VENDOR_IE_ID;
10005 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
10006 qie_age->oui_1 = QCOM_OUI1;
10007 qie_age->oui_2 = QCOM_OUI2;
10008 qie_age->oui_3 = QCOM_OUI3;
10009 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
10010 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
10011#endif
10012
Jeff Johnson295189b2012-06-20 16:38:30 -070010013 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053010014 if (bss_desc->fProbeRsp)
10015 {
10016 mgmt->frame_control |=
10017 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
10018 }
10019 else
10020 {
10021 mgmt->frame_control |=
10022 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
10023 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010024
10025#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010026 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010027 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
10028 {
10029 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10030 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010031 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010032 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
10033
10034 {
10035 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10036 }
10037 else
10038 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010039 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
10040 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070010041 kfree(mgmt);
10042 return NULL;
10043 }
10044#else
10045 freq = ieee80211_channel_to_frequency(chan_no);
10046#endif
10047 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010048 /*when the band is changed on the fly using the GUI, three things are done
10049 * 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)
10050 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
10051 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
10052 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
10053 * and discards the channels correponding to previous band and calls back with zero bss results.
10054 * 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
10055 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
10056 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
10057 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
10058 * So drop the bss and continue to next bss.
10059 */
10060 if(chan == NULL)
10061 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010062 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070010063 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010064 return NULL;
10065 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053010066 /*To keep the rssi icon of the connected AP in the scan window
10067 *and the rssi icon of the wireless networks in sync
10068 * */
10069 if (( eConnectionState_Associated ==
10070 pAdapter->sessionCtx.station.conn_info.connState ) &&
10071 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
10072 pAdapter->sessionCtx.station.conn_info.bssId,
10073 WNI_CFG_BSSID_LEN)) &&
10074 (pHddCtx->hdd_wlan_suspended == FALSE))
10075 {
10076 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
10077 rssi = (pAdapter->rssi * 100);
10078 }
10079 else
10080 {
10081 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
10082 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010083
Nirav Shah20ac06f2013-12-12 18:14:06 +053010084 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053010085 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
10086 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053010087
Jeff Johnson295189b2012-06-20 16:38:30 -070010088 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
10089 frame_len, rssi, GFP_KERNEL);
10090 kfree(mgmt);
10091 return bss_status;
10092}
10093
10094/*
10095 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
10096 * This function is used to update the BSS data base of CFG8011
10097 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010098struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010099 tCsrRoamInfo *pRoamInfo
10100 )
10101{
10102 tCsrRoamConnectedProfile roamProfile;
10103 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10104 struct cfg80211_bss *bss = NULL;
10105
10106 ENTER();
10107
10108 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
10109 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
10110
10111 if (NULL != roamProfile.pBssDesc)
10112 {
Girish Gowlif4b68022014-08-28 23:18:57 +053010113 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10114 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070010115
10116 if (NULL == bss)
10117 {
10118 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
10119 __func__);
10120 }
10121
10122 sme_RoamFreeConnectProfile(hHal, &roamProfile);
10123 }
10124 else
10125 {
10126 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
10127 __func__);
10128 }
10129 return bss;
10130}
10131
10132/*
10133 * FUNCTION: wlan_hdd_cfg80211_update_bss
10134 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010135static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
10136 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070010137 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010138{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010139 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010140 tCsrScanResultInfo *pScanResult;
10141 eHalStatus status = 0;
10142 tScanResultHandle pResult;
10143 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010144 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010145 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070010146 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010147
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010148 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10149 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
10150 NO_SESSION, pAdapter->sessionId));
10151
Wilson Yangf80a0542013-10-07 13:02:37 -070010152 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10153
10154 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070010155 {
Wilson Yangf80a0542013-10-07 13:02:37 -070010156 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10157 "%s:LOGP in Progress. Ignore!!!",__func__);
10158 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010159 }
10160
Wilson Yangf80a0542013-10-07 13:02:37 -070010161
10162 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053010163 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070010164 {
10165 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10166 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
10167 return VOS_STATUS_E_PERM;
10168 }
10169
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010170 if (pAdapter->request != NULL)
10171 {
10172 if ((pAdapter->request->n_ssids == 1)
10173 && (pAdapter->request->ssids != NULL)
10174 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
10175 is_p2p_scan = true;
10176 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010177 /*
10178 * start getting scan results and populate cgf80211 BSS database
10179 */
10180 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
10181
10182 /* no scan results */
10183 if (NULL == pResult)
10184 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010185 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
10186 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053010187 wlan_hdd_get_frame_logs(pAdapter,
10188 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070010189 return status;
10190 }
10191
10192 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
10193
10194 while (pScanResult)
10195 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010196 /*
10197 * cfg80211_inform_bss() is not updating ie field of bss entry, if
10198 * entry already exists in bss data base of cfg80211 for that
10199 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
10200 * bss entry instead of cfg80211_inform_bss, But this call expects
10201 * mgmt packet as input. As of now there is no possibility to get
10202 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070010203 * ieee80211_mgmt(probe response) and passing to c
10204 * fg80211_inform_bss_frame.
10205 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010206 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
10207 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
10208 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010209 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10210 continue; //Skip the non p2p bss entries
10211 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010212 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10213 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010214
Jeff Johnson295189b2012-06-20 16:38:30 -070010215
10216 if (NULL == bss_status)
10217 {
10218 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010219 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010220 }
10221 else
10222 {
Yue Maf49ba872013-08-19 12:04:25 -070010223 cfg80211_put_bss(
10224#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
10225 wiphy,
10226#endif
10227 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010228 }
10229
10230 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10231 }
10232
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010233 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010234 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010235 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010236}
10237
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010238void
10239hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
10240{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010241 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080010242 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010243} /****** end hddPrintMacAddr() ******/
10244
10245void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010246hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010247{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010248 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010249 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010250 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
10251 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
10252 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010253} /****** end hddPrintPmkId() ******/
10254
10255//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
10256//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
10257
10258//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
10259//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
10260
10261#define dump_bssid(bssid) \
10262 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010263 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
10264 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010265 }
10266
10267#define dump_pmkid(pMac, pmkid) \
10268 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010269 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
10270 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010271 }
10272
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070010273#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010274/*
10275 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
10276 * This function is used to notify the supplicant of a new PMKSA candidate.
10277 */
10278int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010279 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010280 int index, bool preauth )
10281{
Jeff Johnsone7245742012-09-05 17:12:55 -070010282#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010283 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010284 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010285
10286 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070010287 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010288
10289 if( NULL == pRoamInfo )
10290 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010291 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010292 return -EINVAL;
10293 }
10294
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010295 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
10296 {
10297 dump_bssid(pRoamInfo->bssid);
10298 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010299 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010300 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010301#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010302 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010303}
10304#endif //FEATURE_WLAN_LFR
10305
Yue Maef608272013-04-08 23:09:17 -070010306#ifdef FEATURE_WLAN_LFR_METRICS
10307/*
10308 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
10309 * 802.11r/LFR metrics reporting function to report preauth initiation
10310 *
10311 */
10312#define MAX_LFR_METRICS_EVENT_LENGTH 100
10313VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
10314 tCsrRoamInfo *pRoamInfo)
10315{
10316 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10317 union iwreq_data wrqu;
10318
10319 ENTER();
10320
10321 if (NULL == pAdapter)
10322 {
10323 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10324 return VOS_STATUS_E_FAILURE;
10325 }
10326
10327 /* create the event */
10328 memset(&wrqu, 0, sizeof(wrqu));
10329 memset(metrics_notification, 0, sizeof(metrics_notification));
10330
10331 wrqu.data.pointer = metrics_notification;
10332 wrqu.data.length = scnprintf(metrics_notification,
10333 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
10334 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10335
10336 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10337
10338 EXIT();
10339
10340 return VOS_STATUS_SUCCESS;
10341}
10342
10343/*
10344 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
10345 * 802.11r/LFR metrics reporting function to report preauth completion
10346 * or failure
10347 */
10348VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
10349 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
10350{
10351 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10352 union iwreq_data wrqu;
10353
10354 ENTER();
10355
10356 if (NULL == pAdapter)
10357 {
10358 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10359 return VOS_STATUS_E_FAILURE;
10360 }
10361
10362 /* create the event */
10363 memset(&wrqu, 0, sizeof(wrqu));
10364 memset(metrics_notification, 0, sizeof(metrics_notification));
10365
10366 scnprintf(metrics_notification, sizeof(metrics_notification),
10367 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
10368 MAC_ADDR_ARRAY(pRoamInfo->bssid));
10369
10370 if (1 == preauth_status)
10371 strncat(metrics_notification, " TRUE", 5);
10372 else
10373 strncat(metrics_notification, " FALSE", 6);
10374
10375 wrqu.data.pointer = metrics_notification;
10376 wrqu.data.length = strlen(metrics_notification);
10377
10378 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10379
10380 EXIT();
10381
10382 return VOS_STATUS_SUCCESS;
10383}
10384
10385/*
10386 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
10387 * 802.11r/LFR metrics reporting function to report handover initiation
10388 *
10389 */
10390VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
10391 tCsrRoamInfo *pRoamInfo)
10392{
10393 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10394 union iwreq_data wrqu;
10395
10396 ENTER();
10397
10398 if (NULL == pAdapter)
10399 {
10400 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10401 return VOS_STATUS_E_FAILURE;
10402 }
10403
10404 /* create the event */
10405 memset(&wrqu, 0, sizeof(wrqu));
10406 memset(metrics_notification, 0, sizeof(metrics_notification));
10407
10408 wrqu.data.pointer = metrics_notification;
10409 wrqu.data.length = scnprintf(metrics_notification,
10410 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
10411 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10412
10413 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10414
10415 EXIT();
10416
10417 return VOS_STATUS_SUCCESS;
10418}
10419#endif
10420
Jeff Johnson295189b2012-06-20 16:38:30 -070010421/*
10422 * FUNCTION: hdd_cfg80211_scan_done_callback
10423 * scanning callback function, called after finishing scan
10424 *
10425 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010426static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070010427 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
10428{
10429 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010430 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070010431 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010432 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010433 struct cfg80211_scan_request *req = NULL;
10434 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010435 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010436 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010437 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010438 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010439
10440 ENTER();
10441
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010442 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053010443 if (NULL == pHddCtx) {
10444 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010445 goto allow_suspend;
10446 }
10447
10448 pScanInfo = &pHddCtx->scan_info;
10449
Jeff Johnson295189b2012-06-20 16:38:30 -070010450 hddLog(VOS_TRACE_LEVEL_INFO,
10451 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080010452 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010453 __func__, halHandle, pContext, (int) scanId, (int) status);
10454
Kiet Lamac06e2c2013-10-23 16:25:07 +053010455 pScanInfo->mScanPendingCounter = 0;
10456
Jeff Johnson295189b2012-06-20 16:38:30 -070010457 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010458 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070010459 &pScanInfo->scan_req_completion_event,
10460 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010461 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070010462 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010463 hddLog(VOS_TRACE_LEVEL_ERROR,
10464 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070010465 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010466 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010467 }
10468
Yue Maef608272013-04-08 23:09:17 -070010469 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010470 {
10471 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010472 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010473 }
10474
10475 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010476 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070010477 {
10478 hddLog(VOS_TRACE_LEVEL_INFO,
10479 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010480 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070010481 (int) scanId);
10482 }
10483
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010484 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010485 pAdapter);
10486
10487 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010488 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010489
10490
10491 /* If any client wait scan result through WEXT
10492 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010493 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070010494 {
10495 /* The other scan request waiting for current scan finish
10496 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010497 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010498 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010499 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070010500 }
10501 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010502 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010503 {
10504 struct net_device *dev = pAdapter->dev;
10505 union iwreq_data wrqu;
10506 int we_event;
10507 char *msg;
10508
10509 memset(&wrqu, '\0', sizeof(wrqu));
10510 we_event = SIOCGIWSCAN;
10511 msg = NULL;
10512 wireless_send_event(dev, we_event, &wrqu, msg);
10513 }
10514 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010515 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010516
10517 /* Get the Scan Req */
10518 req = pAdapter->request;
10519
10520 if (!req)
10521 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010522 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010523 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010524 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010525 }
10526
Jeff Johnson295189b2012-06-20 16:38:30 -070010527 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070010528 /* Scan is no longer pending */
10529 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010530
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010531 /* last_scan_timestamp is used to decide if new scan
10532 * is needed or not on station interface. If last station
10533 * scan time and new station scan time is less then
10534 * last_scan_timestamp ; driver will return cached scan.
10535 */
10536 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
10537 {
10538 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
10539
10540 if ( req->n_channels )
10541 {
10542 for (i = 0; i < req->n_channels ; i++ )
10543 {
10544 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
10545 }
10546 /* store no of channel scanned */
10547 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
10548 }
10549
10550 }
10551
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070010552 /*
10553 * cfg80211_scan_done informing NL80211 about completion
10554 * of scanning
10555 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010556 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
10557 {
10558 aborted = true;
10559 }
10560 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080010561 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010562
Siddharth Bhal76972212014-10-15 16:22:51 +053010563 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
10564 /* Generate new random mac addr for next scan */
10565 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
10566 hdd_processSpoofMacAddrRequest(pHddCtx);
10567 }
10568
Jeff Johnsone7245742012-09-05 17:12:55 -070010569allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010570 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010571 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070010572
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010573 /* Acquire wakelock to handle the case where APP's tries to suspend
10574 * immediatly after the driver gets connect request(i.e after scan)
10575 * from supplicant, this result in app's is suspending and not able
10576 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010577 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010578
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010579#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010580 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010581#endif
10582
Jeff Johnson295189b2012-06-20 16:38:30 -070010583 EXIT();
10584 return 0;
10585}
10586
10587/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053010588 * FUNCTION: hdd_isConnectionInProgress
10589 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010590 *
10591 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010592v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010593{
10594 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10595 hdd_station_ctx_t *pHddStaCtx = NULL;
10596 hdd_adapter_t *pAdapter = NULL;
10597 VOS_STATUS status = 0;
10598 v_U8_t staId = 0;
10599 v_U8_t *staMac = NULL;
10600
c_hpothu9b781ba2013-12-30 20:57:45 +053010601 if (TRUE == pHddCtx->btCoexModeSet)
10602 {
10603 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053010604 FL("BTCoex Mode operation in progress"));
10605 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053010606 }
10607
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010608 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10609
10610 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10611 {
10612 pAdapter = pAdapterNode->pAdapter;
10613
10614 if( pAdapter )
10615 {
10616 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010617 "%s: Adapter with device mode %s (%d) exists",
10618 __func__, hdd_device_modetoString(pAdapter->device_mode),
10619 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010620 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053010621 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10622 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
10623 (eConnectionState_Connecting ==
10624 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
10625 {
10626 hddLog(VOS_TRACE_LEVEL_ERROR,
10627 "%s: %p(%d) Connection is in progress", __func__,
10628 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10629 return VOS_TRUE;
10630 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010631 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053010632 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010633 {
10634 hddLog(VOS_TRACE_LEVEL_ERROR,
10635 "%s: %p(%d) Reassociation is in progress", __func__,
10636 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10637 return VOS_TRUE;
10638 }
10639 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010640 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10641 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010642 {
10643 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10644 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010645 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010646 {
10647 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
10648 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010649 "%s: client " MAC_ADDRESS_STR
10650 " is in the middle of WPS/EAPOL exchange.", __func__,
10651 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010652 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010653 }
10654 }
10655 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
10656 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
10657 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010658 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10659 ptSapContext pSapCtx = NULL;
10660 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10661 if(pSapCtx == NULL){
10662 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10663 FL("psapCtx is NULL"));
10664 return VOS_FALSE;
10665 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010666 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
10667 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010668 if ((pSapCtx->aStaInfo[staId].isUsed) &&
10669 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010670 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010671 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010672
10673 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010674 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
10675 "middle of WPS/EAPOL exchange.", __func__,
10676 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010677 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010678 }
10679 }
10680 }
10681 }
10682 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10683 pAdapterNode = pNext;
10684 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053010685 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010686}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010687
10688/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010689 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070010690 * this scan respond to scan trigger and update cfg80211 scan database
10691 * later, scan dump command can be used to recieve scan results
10692 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010693int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010694#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10695 struct net_device *dev,
10696#endif
10697 struct cfg80211_scan_request *request)
10698{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010699 hdd_adapter_t *pAdapter = NULL;
10700 hdd_context_t *pHddCtx = NULL;
10701 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010702 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010703 tCsrScanRequest scanRequest;
10704 tANI_U8 *channelList = NULL, i;
10705 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010706 int status;
10707 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010708 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010709 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053010710 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010711 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053010712 v_S7_t rssi=0;
10713 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010714
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010715#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
10716 struct net_device *dev = NULL;
10717 if (NULL == request)
10718 {
10719 hddLog(VOS_TRACE_LEVEL_ERROR,
10720 "%s: scan req param null", __func__);
10721 return -EINVAL;
10722 }
10723 dev = request->wdev->netdev;
10724#endif
10725
10726 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
10727 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
10728 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10729
Jeff Johnson295189b2012-06-20 16:38:30 -070010730 ENTER();
10731
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010732 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10733 __func__, hdd_device_modetoString(pAdapter->device_mode),
10734 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010735
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010736 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010737 if (0 != status)
10738 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010739 return status;
10740 }
10741
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010742 if (NULL == pwextBuf)
10743 {
10744 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
10745 __func__);
10746 return -EIO;
10747 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010748 cfg_param = pHddCtx->cfg_ini;
10749 pScanInfo = &pHddCtx->scan_info;
10750
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053010751 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10752 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
10753 {
10754 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
10755 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
10756 }
10757
Jeff Johnson295189b2012-06-20 16:38:30 -070010758#ifdef WLAN_BTAMP_FEATURE
10759 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010760 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070010761 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010762 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010763 "%s: No scanning when AMP is on", __func__);
10764 return -EOPNOTSUPP;
10765 }
10766#endif
10767 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010768 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010769 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010770 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010771 "%s: Not scanning on device_mode = %s (%d)",
10772 __func__, hdd_device_modetoString(pAdapter->device_mode),
10773 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010774 return -EOPNOTSUPP;
10775 }
10776
10777 if (TRUE == pScanInfo->mScanPending)
10778 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010779 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
10780 {
10781 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
10782 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010783 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010784 }
10785
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010786 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070010787 //Channel and action frame is pending
10788 //Otherwise Cancel Remain On Channel and allow Scan
10789 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010790 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070010791 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010792 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010793 return -EBUSY;
10794 }
10795
Jeff Johnson295189b2012-06-20 16:38:30 -070010796 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
10797 {
10798 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080010799 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010800 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010801 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010802 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
10803 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010804 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010805 "%s: MAX TM Level Scan not allowed", __func__);
10806 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010807 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010808 }
10809 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
10810
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010811 /* Check if scan is allowed at this point of time.
10812 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010813 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010814 {
10815 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
10816 return -EBUSY;
10817 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010818
Jeff Johnson295189b2012-06-20 16:38:30 -070010819 vos_mem_zero( &scanRequest, sizeof(scanRequest));
10820
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010821 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
10822 * Becasue of this, driver is assuming that this is not wildcard scan and so
10823 * is not aging out the scan results.
10824 */
10825 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010826 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010827 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010828 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010829
10830 if ((request->ssids) && (0 < request->n_ssids))
10831 {
10832 tCsrSSIDInfo *SsidInfo;
10833 int j;
10834 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
10835 /* Allocate num_ssid tCsrSSIDInfo structure */
10836 SsidInfo = scanRequest.SSIDs.SSIDList =
10837 ( tCsrSSIDInfo *)vos_mem_malloc(
10838 request->n_ssids*sizeof(tCsrSSIDInfo));
10839
10840 if(NULL == scanRequest.SSIDs.SSIDList)
10841 {
10842 hddLog(VOS_TRACE_LEVEL_ERROR,
10843 "%s: memory alloc failed SSIDInfo buffer", __func__);
10844 return -ENOMEM;
10845 }
10846
10847 /* copy all the ssid's and their length */
10848 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
10849 {
10850 /* get the ssid length */
10851 SsidInfo->SSID.length = request->ssids[j].ssid_len;
10852 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
10853 SsidInfo->SSID.length);
10854 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
10855 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
10856 j, SsidInfo->SSID.ssId);
10857 }
10858 /* set the scan type to active */
10859 scanRequest.scanType = eSIR_ACTIVE_SCAN;
10860 }
10861 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070010862 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010863 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10864 TRACE_CODE_HDD_CFG80211_SCAN,
10865 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070010866 /* set the scan type to active */
10867 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010868 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010869 else
10870 {
10871 /*Set the scan type to default type, in this case it is ACTIVE*/
10872 scanRequest.scanType = pScanInfo->scan_mode;
10873 }
10874 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
10875 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070010876
10877 /* set BSSType to default type */
10878 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
10879
10880 /*TODO: scan the requested channels only*/
10881
10882 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010883 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070010884 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010885 hddLog(VOS_TRACE_LEVEL_WARN,
10886 "No of Scan Channels exceeded limit: %d", request->n_channels);
10887 request->n_channels = MAX_CHANNEL;
10888 }
10889
10890 hddLog(VOS_TRACE_LEVEL_INFO,
10891 "No of Scan Channels: %d", request->n_channels);
10892
10893
10894 if( request->n_channels )
10895 {
10896 char chList [(request->n_channels*5)+1];
10897 int len;
10898 channelList = vos_mem_malloc( request->n_channels );
10899 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053010900 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010901 hddLog(VOS_TRACE_LEVEL_ERROR,
10902 "%s: memory alloc failed channelList", __func__);
10903 status = -ENOMEM;
10904 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053010905 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010906
10907 for( i = 0, len = 0; i < request->n_channels ; i++ )
10908 {
10909 channelList[i] = request->channels[i]->hw_value;
10910 len += snprintf(chList+len, 5, "%d ", channelList[i]);
10911 }
10912
Nirav Shah20ac06f2013-12-12 18:14:06 +053010913 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010914 "Channel-List: %s ", chList);
10915 }
c_hpothu53512302014-04-15 18:49:53 +053010916
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010917 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
10918 scanRequest.ChannelInfo.ChannelList = channelList;
10919
10920 /* set requestType to full scan */
10921 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10922
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010923 /* if there is back to back scan happening in driver with in
10924 * nDeferScanTimeInterval interval driver should defer new scan request
10925 * and should provide last cached scan results instead of new channel list.
10926 * This rule is not applicable if scan is p2p scan.
10927 * This condition will work only in case when last request no of channels
10928 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053010929 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053010930 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010931 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010932
Sushant Kaushik86592172015-04-27 16:35:03 +053010933 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
10934 /* if wps ie is NULL , then only defer scan */
10935 if ( pWpsIe == NULL &&
10936 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053010937 {
10938 if ( pScanInfo->last_scan_timestamp !=0 &&
10939 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
10940 {
10941 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
10942 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
10943 vos_mem_compare(pScanInfo->last_scan_channelList,
10944 channelList, pScanInfo->last_scan_numChannels))
10945 {
10946 hddLog(VOS_TRACE_LEVEL_WARN,
10947 " New and old station scan time differ is less then %u",
10948 pHddCtx->cfg_ini->nDeferScanTimeInterval);
10949
10950 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010951 pAdapter);
10952
Agarwal Ashish57e84372014-12-05 18:26:53 +053010953 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010954 "Return old cached scan as all channels and no of channels are same");
10955
Agarwal Ashish57e84372014-12-05 18:26:53 +053010956 if (0 > ret)
10957 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010958
Agarwal Ashish57e84372014-12-05 18:26:53 +053010959 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010960
10961 status = eHAL_STATUS_SUCCESS;
10962 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053010963 }
10964 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010965 }
10966
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010967 /* Flush the scan results(only p2p beacons) for STA scan and P2P
10968 * search (Flush on both full scan and social scan but not on single
10969 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
10970 */
10971
10972 /* Supplicant does single channel scan after 8-way handshake
10973 * and in that case driver shoudnt flush scan results. If
10974 * driver flushes the scan results here and unfortunately if
10975 * the AP doesnt respond to our probe req then association
10976 * fails which is not desired
10977 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010978 if ((request->n_ssids == 1)
10979 && (request->ssids != NULL)
10980 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
10981 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010982
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010983 if( is_p2p_scan ||
10984 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010985 {
10986 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
10987 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
10988 pAdapter->sessionId );
10989 }
10990
10991 if( request->ie_len )
10992 {
10993 /* save this for future association (join requires this) */
10994 /*TODO: Array needs to be converted to dynamic allocation,
10995 * as multiple ie.s can be sent in cfg80211_scan_request structure
10996 * CR 597966
10997 */
10998 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
10999 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
11000 pScanInfo->scanAddIE.length = request->ie_len;
11001
11002 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11003 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11004 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011005 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011006 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070011007 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011008 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
11009 memcpy( pwextBuf->roamProfile.addIEScan,
11010 request->ie, request->ie_len);
11011 }
11012 else
11013 {
11014 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
11015 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011016 }
11017
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011018 }
11019 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
11020 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
11021
11022 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
11023 request->ie_len);
11024 if (pP2pIe != NULL)
11025 {
11026#ifdef WLAN_FEATURE_P2P_DEBUG
11027 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
11028 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
11029 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053011030 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011031 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
11032 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11033 "Go nego completed to Connection is started");
11034 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11035 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053011036 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011037 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
11038 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011039 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011040 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
11041 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11042 "Disconnected state to Connection is started");
11043 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11044 "for 4way Handshake");
11045 }
11046#endif
11047
11048 /* no_cck will be set during p2p find to disable 11b rates */
11049 if(TRUE == request->no_cck)
11050 {
11051 hddLog(VOS_TRACE_LEVEL_INFO,
11052 "%s: This is a P2P Search", __func__);
11053 scanRequest.p2pSearch = 1;
11054
11055 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053011056 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011057 /* set requestType to P2P Discovery */
11058 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
11059 }
11060
11061 /*
11062 Skip Dfs Channel in case of P2P Search
11063 if it is set in ini file
11064 */
11065 if(cfg_param->skipDfsChnlInP2pSearch)
11066 {
11067 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011068 }
11069 else
11070 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011071 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011072 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011073
Agarwal Ashish4f616132013-12-30 23:32:50 +053011074 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011075 }
11076 }
11077
11078 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
11079
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011080#ifdef FEATURE_WLAN_TDLS
11081 /* if tdls disagree scan right now, return immediately.
11082 tdls will schedule the scan when scan is allowed. (return SUCCESS)
11083 or will reject the scan if any TDLS is in progress. (return -EBUSY)
11084 */
11085 status = wlan_hdd_tdls_scan_callback (pAdapter,
11086 wiphy,
11087#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11088 dev,
11089#endif
11090 request);
11091 if(status <= 0)
11092 {
11093 if(!status)
11094 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
11095 "scan rejected %d", __func__, status);
11096 else
11097 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
11098 __func__, status);
11099
11100 return status;
11101 }
11102#endif
11103
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011104 /* acquire the wakelock to avoid the apps suspend during the scan. To
11105 * address the following issues.
11106 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
11107 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
11108 * for long time, this result in apps running at full power for long time.
11109 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
11110 * be stuck in full power because of resume BMPS
11111 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011112 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011113
Nirav Shah20ac06f2013-12-12 18:14:06 +053011114 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11115 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011116 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
11117 scanRequest.requestType, scanRequest.scanType,
11118 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053011119 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
11120
Siddharth Bhal76972212014-10-15 16:22:51 +053011121 if (pHddCtx->spoofMacAddr.isEnabled)
11122 {
11123 hddLog(VOS_TRACE_LEVEL_INFO,
11124 "%s: MAC Spoofing enabled for current scan", __func__);
11125 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
11126 * to fill TxBds for probe request during current scan
11127 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011128 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053011129 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011130
11131 if(status != VOS_STATUS_SUCCESS)
11132 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011133 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011134 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053011135#ifdef FEATURE_WLAN_TDLS
11136 wlan_hdd_tdls_scan_done_callback(pAdapter);
11137#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011138 goto free_mem;
11139 }
Siddharth Bhal76972212014-10-15 16:22:51 +053011140 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053011141 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070011142 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011143 pAdapter->sessionId, &scanRequest, &scanId,
11144 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070011145
Jeff Johnson295189b2012-06-20 16:38:30 -070011146 if (eHAL_STATUS_SUCCESS != status)
11147 {
11148 hddLog(VOS_TRACE_LEVEL_ERROR,
11149 "%s: sme_ScanRequest returned error %d", __func__, status);
11150 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011151 if(eHAL_STATUS_RESOURCES == status)
11152 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011153 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
11154 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011155 status = -EBUSY;
11156 } else {
11157 status = -EIO;
11158 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011159 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011160
11161#ifdef FEATURE_WLAN_TDLS
11162 wlan_hdd_tdls_scan_done_callback(pAdapter);
11163#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011164 goto free_mem;
11165 }
11166
11167 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011168 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011169 pAdapter->request = request;
11170 pScanInfo->scanId = scanId;
11171
11172 complete(&pScanInfo->scan_req_completion_event);
11173
11174free_mem:
11175 if( scanRequest.SSIDs.SSIDList )
11176 {
11177 vos_mem_free(scanRequest.SSIDs.SSIDList);
11178 }
11179
11180 if( channelList )
11181 vos_mem_free( channelList );
11182
11183 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011184 return status;
11185}
11186
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011187int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
11188#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11189 struct net_device *dev,
11190#endif
11191 struct cfg80211_scan_request *request)
11192{
11193 int ret;
11194
11195 vos_ssr_protect(__func__);
11196 ret = __wlan_hdd_cfg80211_scan(wiphy,
11197#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11198 dev,
11199#endif
11200 request);
11201 vos_ssr_unprotect(__func__);
11202
11203 return ret;
11204}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011205
11206void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
11207{
11208 v_U8_t iniDot11Mode =
11209 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
11210 eHddDot11Mode hddDot11Mode = iniDot11Mode;
11211
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011212 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
11213 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011214 switch ( iniDot11Mode )
11215 {
11216 case eHDD_DOT11_MODE_AUTO:
11217 case eHDD_DOT11_MODE_11ac:
11218 case eHDD_DOT11_MODE_11ac_ONLY:
11219#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053011220 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
11221 sme_IsFeatureSupportedByFW(DOT11AC) )
11222 hddDot11Mode = eHDD_DOT11_MODE_11ac;
11223 else
11224 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011225#else
11226 hddDot11Mode = eHDD_DOT11_MODE_11n;
11227#endif
11228 break;
11229 case eHDD_DOT11_MODE_11n:
11230 case eHDD_DOT11_MODE_11n_ONLY:
11231 hddDot11Mode = eHDD_DOT11_MODE_11n;
11232 break;
11233 default:
11234 hddDot11Mode = iniDot11Mode;
11235 break;
11236 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011237#ifdef WLAN_FEATURE_AP_HT40_24G
11238 if (operationChannel > SIR_11B_CHANNEL_END)
11239#endif
11240 {
11241 /* This call decides required channel bonding mode */
11242 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011243 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
11244 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011245 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011246}
11247
Jeff Johnson295189b2012-06-20 16:38:30 -070011248/*
11249 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011250 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011251 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011252int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011253 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070011254{
11255 int status = 0;
11256 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080011257 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011258 v_U32_t roamId;
11259 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070011260 eCsrAuthType RSNAuthType;
11261
11262 ENTER();
11263
11264 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080011265 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11266
11267 status = wlan_hdd_validate_context(pHddCtx);
11268 if (status)
11269 {
Yue Mae36e3552014-03-05 17:06:20 -080011270 return status;
11271 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011272
Jeff Johnson295189b2012-06-20 16:38:30 -070011273 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
11274 {
11275 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
11276 return -EINVAL;
11277 }
11278
11279 pRoamProfile = &pWextState->roamProfile;
11280
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011281 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070011282 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011283 hdd_station_ctx_t *pHddStaCtx;
11284 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011285
Siddharth Bhalda0d1622015-04-24 15:47:49 +053011286 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
11287
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011288 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070011289 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
11290 {
11291 /*QoS not enabled in cfg file*/
11292 pRoamProfile->uapsd_mask = 0;
11293 }
11294 else
11295 {
11296 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011297 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070011298 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
11299 }
11300
11301 pRoamProfile->SSIDs.numOfSSIDs = 1;
11302 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
11303 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011304 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070011305 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
11306 ssid, ssid_len);
11307
11308 if (bssid)
11309 {
11310 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
11311 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
11312 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011313 /* Save BSSID in seperate variable as well, as RoamProfile
11314 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070011315 case of join failure we should send valid BSSID to supplicant
11316 */
11317 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
11318 WNI_CFG_BSSID_LEN);
11319 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070011320 else
11321 {
11322 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
11323 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011324
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011325 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
11326 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011327 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
11328 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011329 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011330 /*set gen ie*/
11331 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
11332 /*set auth*/
11333 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
11334 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011335#ifdef FEATURE_WLAN_WAPI
11336 if (pAdapter->wapi_info.nWapiMode)
11337 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011338 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011339 switch (pAdapter->wapi_info.wapiAuthMode)
11340 {
11341 case WAPI_AUTH_MODE_PSK:
11342 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011343 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011344 pAdapter->wapi_info.wapiAuthMode);
11345 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
11346 break;
11347 }
11348 case WAPI_AUTH_MODE_CERT:
11349 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011350 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011351 pAdapter->wapi_info.wapiAuthMode);
11352 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
11353 break;
11354 }
11355 } // End of switch
11356 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
11357 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
11358 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011359 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011360 pRoamProfile->AuthType.numEntries = 1;
11361 pRoamProfile->EncryptionType.numEntries = 1;
11362 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11363 pRoamProfile->mcEncryptionType.numEntries = 1;
11364 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11365 }
11366 }
11367#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011368#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011369 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011370 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11371 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
11372 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011373 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
11374 sizeof (tSirGtkOffloadParams));
11375 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011376 }
11377#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011378 pRoamProfile->csrPersona = pAdapter->device_mode;
11379
Jeff Johnson32d95a32012-09-10 13:15:23 -070011380 if( operatingChannel )
11381 {
11382 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
11383 pRoamProfile->ChannelInfo.numOfChannels = 1;
11384 }
Chet Lanctot186b5732013-03-18 10:26:30 -070011385 else
11386 {
11387 pRoamProfile->ChannelInfo.ChannelList = NULL;
11388 pRoamProfile->ChannelInfo.numOfChannels = 0;
11389 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011390 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
11391 {
11392 hdd_select_cbmode(pAdapter,operatingChannel);
11393 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011394
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011395 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
11396 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011397 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011398 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011399 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
11400 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011401 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11402 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053011403 {
11404 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11405 "%s: Set HDD connState to eConnectionState_Connecting",
11406 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011407 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
11408 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053011409 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011410 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011411 pAdapter->sessionId, pRoamProfile, &roamId);
11412
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011413 if ((eHAL_STATUS_SUCCESS != status) &&
11414 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11415 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011416
11417 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011418 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
11419 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
11420 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011421 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011422 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011423 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011424
11425 pRoamProfile->ChannelInfo.ChannelList = NULL;
11426 pRoamProfile->ChannelInfo.numOfChannels = 0;
11427
Jeff Johnson295189b2012-06-20 16:38:30 -070011428 }
11429 else
11430 {
11431 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
11432 return -EINVAL;
11433 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011434 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011435 return status;
11436}
11437
11438/*
11439 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
11440 * This function is used to set the authentication type (OPEN/SHARED).
11441 *
11442 */
11443static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
11444 enum nl80211_auth_type auth_type)
11445{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011446 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011447 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11448
11449 ENTER();
11450
11451 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011452 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070011453 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011454 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011455 hddLog(VOS_TRACE_LEVEL_INFO,
11456 "%s: set authentication type to AUTOSWITCH", __func__);
11457 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
11458 break;
11459
11460 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011461#ifdef WLAN_FEATURE_VOWIFI_11R
11462 case NL80211_AUTHTYPE_FT:
11463#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011464 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011465 "%s: set authentication type to OPEN", __func__);
11466 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
11467 break;
11468
11469 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011470 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011471 "%s: set authentication type to SHARED", __func__);
11472 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
11473 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011474#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011475 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011476 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011477 "%s: set authentication type to CCKM WPA", __func__);
11478 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
11479 break;
11480#endif
11481
11482
11483 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011484 hddLog(VOS_TRACE_LEVEL_ERROR,
11485 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011486 auth_type);
11487 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
11488 return -EINVAL;
11489 }
11490
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011491 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011492 pHddStaCtx->conn_info.authType;
11493 return 0;
11494}
11495
11496/*
11497 * FUNCTION: wlan_hdd_set_akm_suite
11498 * This function is used to set the key mgmt type(PSK/8021x).
11499 *
11500 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011501static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011502 u32 key_mgmt
11503 )
11504{
11505 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11506 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053011507 /* Should be in ieee802_11_defs.h */
11508#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
11509#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070011510 /*set key mgmt type*/
11511 switch(key_mgmt)
11512 {
11513 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053011514 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011515#ifdef WLAN_FEATURE_VOWIFI_11R
11516 case WLAN_AKM_SUITE_FT_PSK:
11517#endif
11518 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070011519 __func__);
11520 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
11521 break;
11522
11523 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053011524 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011525#ifdef WLAN_FEATURE_VOWIFI_11R
11526 case WLAN_AKM_SUITE_FT_8021X:
11527#endif
11528 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070011529 __func__);
11530 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11531 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011532#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011533#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
11534#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
11535 case WLAN_AKM_SUITE_CCKM:
11536 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
11537 __func__);
11538 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
11539 break;
11540#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070011541#ifndef WLAN_AKM_SUITE_OSEN
11542#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
11543 case WLAN_AKM_SUITE_OSEN:
11544 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
11545 __func__);
11546 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11547 break;
11548#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011549
11550 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011551 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011552 __func__, key_mgmt);
11553 return -EINVAL;
11554
11555 }
11556 return 0;
11557}
11558
11559/*
11560 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011561 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070011562 * (NONE/WEP40/WEP104/TKIP/CCMP).
11563 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011564static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
11565 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070011566 bool ucast
11567 )
11568{
11569 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011570 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011571 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11572
11573 ENTER();
11574
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011575 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011576 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011577 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070011578 __func__, cipher);
11579 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11580 }
11581 else
11582 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011583
Jeff Johnson295189b2012-06-20 16:38:30 -070011584 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011585 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011586 {
11587 case IW_AUTH_CIPHER_NONE:
11588 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11589 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011590
Jeff Johnson295189b2012-06-20 16:38:30 -070011591 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011592 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070011593 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011594
Jeff Johnson295189b2012-06-20 16:38:30 -070011595 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011596 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070011597 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011598
Jeff Johnson295189b2012-06-20 16:38:30 -070011599 case WLAN_CIPHER_SUITE_TKIP:
11600 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
11601 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011602
Jeff Johnson295189b2012-06-20 16:38:30 -070011603 case WLAN_CIPHER_SUITE_CCMP:
11604 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11605 break;
11606#ifdef FEATURE_WLAN_WAPI
11607 case WLAN_CIPHER_SUITE_SMS4:
11608 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
11609 break;
11610#endif
11611
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011612#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011613 case WLAN_CIPHER_SUITE_KRK:
11614 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
11615 break;
11616#endif
11617 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011618 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011619 __func__, cipher);
11620 return -EOPNOTSUPP;
11621 }
11622 }
11623
11624 if (ucast)
11625 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011626 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011627 __func__, encryptionType);
11628 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11629 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011630 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011631 encryptionType;
11632 }
11633 else
11634 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011635 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011636 __func__, encryptionType);
11637 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
11638 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
11639 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
11640 }
11641
11642 return 0;
11643}
11644
11645
11646/*
11647 * FUNCTION: wlan_hdd_cfg80211_set_ie
11648 * This function is used to parse WPA/RSN IE's.
11649 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011650int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011651#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11652 const u8 *ie,
11653#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011654 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011655#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011656 size_t ie_len
11657 )
11658{
11659 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011660#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11661 const u8 *genie = ie;
11662#else
Jeff Johnson295189b2012-06-20 16:38:30 -070011663 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011664#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011665 v_U16_t remLen = ie_len;
11666#ifdef FEATURE_WLAN_WAPI
11667 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
11668 u16 *tmp;
11669 v_U16_t akmsuiteCount;
11670 int *akmlist;
11671#endif
11672 ENTER();
11673
11674 /* clear previous assocAddIE */
11675 pWextState->assocAddIE.length = 0;
11676 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011677 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011678
11679 while (remLen >= 2)
11680 {
11681 v_U16_t eLen = 0;
11682 v_U8_t elementId;
11683 elementId = *genie++;
11684 eLen = *genie++;
11685 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011686
Arif Hussain6d2a3322013-11-17 19:50:10 -080011687 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070011688 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011689
11690 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070011691 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011692 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011693 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 -070011694 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011695 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011696 "%s: Invalid WPA IE", __func__);
11697 return -EINVAL;
11698 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011699 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070011700 {
11701 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011702 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011703 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011704
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011705 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011706 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011707 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
11708 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011709 VOS_ASSERT(0);
11710 return -ENOMEM;
11711 }
11712 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11713 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11714 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011715
Jeff Johnson295189b2012-06-20 16:38:30 -070011716 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
11717 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11718 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11719 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011720 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
11721 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011722 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
11723 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11724 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
11725 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
11726 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
11727 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011728 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053011729 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011730 {
11731 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011732 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011733 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011734
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011735 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011736 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011737 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11738 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011739 VOS_ASSERT(0);
11740 return -ENOMEM;
11741 }
11742 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11743 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11744 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011745
Jeff Johnson295189b2012-06-20 16:38:30 -070011746 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11747 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11748 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011749#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011750 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
11751 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011752 /*Consider WFD IE, only for P2P Client */
11753 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11754 {
11755 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011756 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011757 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011758
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011759 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011760 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011761 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11762 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011763 VOS_ASSERT(0);
11764 return -ENOMEM;
11765 }
11766 // WFD IE is saved to Additional IE ; it should be accumulated to handle
11767 // WPS IE + P2P IE + WFD IE
11768 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11769 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011770
Jeff Johnson295189b2012-06-20 16:38:30 -070011771 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11772 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11773 }
11774#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011775 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011776 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011777 HS20_OUI_TYPE_SIZE)) )
11778 {
11779 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011780 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011781 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011782
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011783 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011784 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011785 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11786 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011787 VOS_ASSERT(0);
11788 return -ENOMEM;
11789 }
11790 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11791 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011792
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011793 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11794 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11795 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011796 /* Appending OSEN Information Element in Assiciation Request */
11797 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
11798 OSEN_OUI_TYPE_SIZE)) )
11799 {
11800 v_U16_t curAddIELen = pWextState->assocAddIE.length;
11801 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
11802 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011803
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011804 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011805 {
11806 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11807 "Need bigger buffer space");
11808 VOS_ASSERT(0);
11809 return -ENOMEM;
11810 }
11811 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11812 pWextState->assocAddIE.length += eLen + 2;
11813
11814 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
11815 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11816 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11817 }
11818
Abhishek Singh4322e622015-06-10 15:42:54 +053011819 /* Update only for WPA IE */
11820 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
11821 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070011822
11823 /* populating as ADDIE in beacon frames */
11824 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011825 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070011826 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
11827 {
11828 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11829 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
11830 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11831 {
11832 hddLog(LOGE,
11833 "Coldn't pass "
11834 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
11835 }
11836 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
11837 else
11838 hddLog(LOGE,
11839 "Could not pass on "
11840 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
11841
11842 /* IBSS mode doesn't contain params->proberesp_ies still
11843 beaconIE's need to be populated in probe response frames */
11844 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
11845 {
11846 u16 rem_probe_resp_ie_len = eLen + 2;
11847 u8 probe_rsp_ie_len[3] = {0};
11848 u8 counter = 0;
11849
11850 /* Check Probe Resp Length if it is greater then 255 then
11851 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
11852 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
11853 not able Store More then 255 bytes into One Variable */
11854
11855 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
11856 {
11857 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
11858 {
11859 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
11860 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
11861 }
11862 else
11863 {
11864 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
11865 rem_probe_resp_ie_len = 0;
11866 }
11867 }
11868
11869 rem_probe_resp_ie_len = 0;
11870
11871 if (probe_rsp_ie_len[0] > 0)
11872 {
11873 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11874 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
11875 (tANI_U8*)(genie - 2),
11876 probe_rsp_ie_len[0], NULL,
11877 eANI_BOOLEAN_FALSE)
11878 == eHAL_STATUS_FAILURE)
11879 {
11880 hddLog(LOGE,
11881 "Could not pass"
11882 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
11883 }
11884 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
11885 }
11886
11887 if (probe_rsp_ie_len[1] > 0)
11888 {
11889 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11890 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
11891 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11892 probe_rsp_ie_len[1], NULL,
11893 eANI_BOOLEAN_FALSE)
11894 == eHAL_STATUS_FAILURE)
11895 {
11896 hddLog(LOGE,
11897 "Could not pass"
11898 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
11899 }
11900 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
11901 }
11902
11903 if (probe_rsp_ie_len[2] > 0)
11904 {
11905 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11906 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
11907 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11908 probe_rsp_ie_len[2], NULL,
11909 eANI_BOOLEAN_FALSE)
11910 == eHAL_STATUS_FAILURE)
11911 {
11912 hddLog(LOGE,
11913 "Could not pass"
11914 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
11915 }
11916 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
11917 }
11918
11919 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11920 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
11921 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11922 {
11923 hddLog(LOGE,
11924 "Could not pass"
11925 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
11926 }
11927 }
11928 else
11929 {
11930 // Reset WNI_CFG_PROBE_RSP Flags
11931 wlan_hdd_reset_prob_rspies(pAdapter);
11932
11933 hddLog(VOS_TRACE_LEVEL_INFO,
11934 "%s: No Probe Response IE received in set beacon",
11935 __func__);
11936 }
11937 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070011938 break;
11939 case DOT11F_EID_RSN:
11940 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
11941 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11942 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
11943 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
11944 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
11945 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053011946
11947 /* Appending Extended Capabilities with Interworking bit set
11948 * in Assoc Req.
11949 *
11950 * In assoc req this EXT Cap will only be taken into account if
11951 * interworkingService bit is set to 1. Currently
11952 * driver is only interested in interworkingService capability
11953 * from supplicant. If in future any other EXT Cap info is
11954 * required from supplicat, it needs to be handled while
11955 * sending Assoc Req in LIM.
11956 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011957 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011958 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011959 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011960 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011961 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011962
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011963 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011964 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011965 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11966 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011967 VOS_ASSERT(0);
11968 return -ENOMEM;
11969 }
11970 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11971 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011972
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011973 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11974 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11975 break;
11976 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011977#ifdef FEATURE_WLAN_WAPI
11978 case WLAN_EID_WAPI:
11979 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070011980 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070011981 pAdapter->wapi_info.nWapiMode);
11982 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011983 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070011984 akmsuiteCount = WPA_GET_LE16(tmp);
11985 tmp = tmp + 1;
11986 akmlist = (int *)(tmp);
11987 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
11988 {
11989 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
11990 }
11991 else
11992 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080011993 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070011994 VOS_ASSERT(0);
11995 return -EINVAL;
11996 }
11997
11998 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
11999 {
12000 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012001 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012002 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012003 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012004 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012005 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012006 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012007 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012008 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
12009 }
12010 break;
12011#endif
12012 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012013 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012014 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012015 /* when Unknown IE is received we should break and continue
12016 * to the next IE in the buffer instead we were returning
12017 * so changing this to break */
12018 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070012019 }
12020 genie += eLen;
12021 remLen -= eLen;
12022 }
12023 EXIT();
12024 return 0;
12025}
12026
12027/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012028 * FUNCTION: hdd_isWPAIEPresent
12029 * Parse the received IE to find the WPA IE
12030 *
12031 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012032static bool hdd_isWPAIEPresent(
12033#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
12034 const u8 *ie,
12035#else
12036 u8 *ie,
12037#endif
12038 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012039{
12040 v_U8_t eLen = 0;
12041 v_U16_t remLen = ie_len;
12042 v_U8_t elementId = 0;
12043
12044 while (remLen >= 2)
12045 {
12046 elementId = *ie++;
12047 eLen = *ie++;
12048 remLen -= 2;
12049 if (eLen > remLen)
12050 {
12051 hddLog(VOS_TRACE_LEVEL_ERROR,
12052 "%s: IE length is wrong %d", __func__, eLen);
12053 return FALSE;
12054 }
12055 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
12056 {
12057 /* OUI - 0x00 0X50 0XF2
12058 WPA Information Element - 0x01
12059 WPA version - 0x01*/
12060 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
12061 return TRUE;
12062 }
12063 ie += eLen;
12064 remLen -= eLen;
12065 }
12066 return FALSE;
12067}
12068
12069/*
Jeff Johnson295189b2012-06-20 16:38:30 -070012070 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012071 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012072 * parameters during connect operation.
12073 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012074int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012075 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012076 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012077{
12078 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012079 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012080 ENTER();
12081
12082 /*set wpa version*/
12083 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
12084
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012085 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012086 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053012087 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012088 {
12089 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12090 }
12091 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
12092 {
12093 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12094 }
12095 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012096
12097 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012098 pWextState->wpaVersion);
12099
12100 /*set authentication type*/
12101 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
12102
12103 if (0 > status)
12104 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012105 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012106 "%s: failed to set authentication type ", __func__);
12107 return status;
12108 }
12109
12110 /*set key mgmt type*/
12111 if (req->crypto.n_akm_suites)
12112 {
12113 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
12114 if (0 > status)
12115 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012116 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070012117 __func__);
12118 return status;
12119 }
12120 }
12121
12122 /*set pairwise cipher type*/
12123 if (req->crypto.n_ciphers_pairwise)
12124 {
12125 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
12126 req->crypto.ciphers_pairwise[0], true);
12127 if (0 > status)
12128 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012129 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012130 "%s: failed to set unicast cipher type", __func__);
12131 return status;
12132 }
12133 }
12134 else
12135 {
12136 /*Reset previous cipher suite to none*/
12137 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
12138 if (0 > status)
12139 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012140 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012141 "%s: failed to set unicast cipher type", __func__);
12142 return status;
12143 }
12144 }
12145
12146 /*set group cipher type*/
12147 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
12148 false);
12149
12150 if (0 > status)
12151 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012152 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070012153 __func__);
12154 return status;
12155 }
12156
Chet Lanctot186b5732013-03-18 10:26:30 -070012157#ifdef WLAN_FEATURE_11W
12158 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
12159#endif
12160
Jeff Johnson295189b2012-06-20 16:38:30 -070012161 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
12162 if (req->ie_len)
12163 {
12164 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
12165 if ( 0 > status)
12166 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012167 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012168 __func__);
12169 return status;
12170 }
12171 }
12172
12173 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012174 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012175 {
12176 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
12177 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
12178 )
12179 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012180 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070012181 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
12182 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012183 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012184 __func__);
12185 return -EOPNOTSUPP;
12186 }
12187 else
12188 {
12189 u8 key_len = req->key_len;
12190 u8 key_idx = req->key_idx;
12191
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012192 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012193 && (CSR_MAX_NUM_KEY > key_idx)
12194 )
12195 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012196 hddLog(VOS_TRACE_LEVEL_INFO,
12197 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012198 __func__, key_idx, key_len);
12199 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012200 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012201 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012202 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012203 (u8)key_len;
12204 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
12205 }
12206 }
12207 }
12208 }
12209
12210 return status;
12211}
12212
12213/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012214 * FUNCTION: wlan_hdd_try_disconnect
12215 * This function is used to disconnect from previous
12216 * connection
12217 */
12218static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
12219{
12220 long ret = 0;
12221 hdd_station_ctx_t *pHddStaCtx;
12222 eMib_dot11DesiredBssType connectedBssType;
12223
12224 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12225
12226 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
12227
12228 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
12229 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
12230 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
12231 {
12232 /* Issue disconnect to CSR */
12233 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12234 if( eHAL_STATUS_SUCCESS ==
12235 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12236 pAdapter->sessionId,
12237 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12238 {
12239 ret = wait_for_completion_interruptible_timeout(
12240 &pAdapter->disconnect_comp_var,
12241 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12242 if (0 >= ret)
12243 {
12244 hddLog(LOGE, FL("Failed to receive disconnect event"));
12245 return -EALREADY;
12246 }
12247 }
12248 }
12249 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
12250 {
12251 ret = wait_for_completion_interruptible_timeout(
12252 &pAdapter->disconnect_comp_var,
12253 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12254 if (0 >= ret)
12255 {
12256 hddLog(LOGE, FL("Failed to receive disconnect event"));
12257 return -EALREADY;
12258 }
12259 }
12260
12261 return 0;
12262}
12263
12264/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053012265 * FUNCTION: __wlan_hdd_cfg80211_connect
12266 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070012267 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012268static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012269 struct net_device *ndev,
12270 struct cfg80211_connect_params *req
12271 )
12272{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012273 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012274 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012275 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053012276 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012277
12278 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012279
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012280 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12281 TRACE_CODE_HDD_CFG80211_CONNECT,
12282 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012283 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012284 "%s: device_mode = %s (%d)", __func__,
12285 hdd_device_modetoString(pAdapter->device_mode),
12286 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012287
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012288 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012289 if (!pHddCtx)
12290 {
12291 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12292 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053012293 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012294 }
12295
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012296 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012297 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012298 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012299 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012300 }
12301
Agarwal Ashish51325b52014-06-16 16:50:49 +053012302 if (vos_max_concurrent_connections_reached()) {
12303 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12304 return -ECONNREFUSED;
12305 }
12306
Jeff Johnson295189b2012-06-20 16:38:30 -070012307#ifdef WLAN_BTAMP_FEATURE
12308 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012309 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070012310 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012311 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012312 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012313 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070012314 }
12315#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012316
12317 //If Device Mode is Station Concurrent Sessions Exit BMps
12318 //P2P Mode will be taken care in Open/close adapter
12319 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012320 (vos_concurrent_open_sessions_running())) {
12321 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
12322 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012323 }
12324
12325 /*Try disconnecting if already in connected state*/
12326 status = wlan_hdd_try_disconnect(pAdapter);
12327 if ( 0 > status)
12328 {
12329 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12330 " connection"));
12331 return -EALREADY;
12332 }
12333
Jeff Johnson295189b2012-06-20 16:38:30 -070012334 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012335 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070012336
12337 if ( 0 > status)
12338 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012339 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070012340 __func__);
12341 return status;
12342 }
Mohit Khanna765234a2012-09-11 15:08:35 -070012343 if ( req->channel )
12344 {
12345 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
12346 req->ssid_len, req->bssid,
12347 req->channel->hw_value);
12348 }
12349 else
12350 {
12351 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012352 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070012353 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012354
Sushant Kaushikd7083982015-03-18 14:33:24 +053012355 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012356 {
12357 //ReEnable BMPS if disabled
12358 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
12359 (NULL != pHddCtx))
12360 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012361 if (pHddCtx->hdd_wlan_suspended)
12362 {
12363 hdd_set_pwrparams(pHddCtx);
12364 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012365 //ReEnable Bmps and Imps back
12366 hdd_enable_bmps_imps(pHddCtx);
12367 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053012368 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070012369 return status;
12370 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012371 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012372 EXIT();
12373 return status;
12374}
12375
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012376static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
12377 struct net_device *ndev,
12378 struct cfg80211_connect_params *req)
12379{
12380 int ret;
12381 vos_ssr_protect(__func__);
12382 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
12383 vos_ssr_unprotect(__func__);
12384
12385 return ret;
12386}
Jeff Johnson295189b2012-06-20 16:38:30 -070012387
12388/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012389 * FUNCTION: wlan_hdd_disconnect
12390 * This function is used to issue a disconnect request to SME
12391 */
12392int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
12393{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012394 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012395 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012396 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012397 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012398
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012399 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012400
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012401 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012402 if (0 != status)
12403 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012404 return status;
12405 }
12406
Sushant Kaushikb4834d22015-07-15 15:29:05 +053012407 if (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)
12408 {
12409 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
12410 pAdapter->sessionId);
12411 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012412 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012413
Agarwal Ashish47d18112014-08-04 19:55:07 +053012414 /* Need to apply spin lock before decreasing active sessions
12415 * as there can be chance for double decrement if context switch
12416 * Calls hdd_DisConnectHandler.
12417 */
12418
12419 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012420 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
12421 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012422 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
12423 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053012424 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
12425 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012426
Abhishek Singhf4669da2014-05-26 15:07:49 +053012427 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053012428 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
12429
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012430 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012431
Mihir Shete182a0b22014-08-18 16:08:48 +053012432 /*
12433 * stop tx queues before deleting STA/BSS context from the firmware.
12434 * tx has to be disabled because the firmware can get busy dropping
12435 * the tx frames after BSS/STA has been deleted and will not send
12436 * back a response resulting in WDI timeout
12437 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053012438 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053012439 netif_tx_disable(pAdapter->dev);
12440 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012441
Mihir Shete182a0b22014-08-18 16:08:48 +053012442 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012443 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12444 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012445 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
12446 {
12447 hddLog(VOS_TRACE_LEVEL_INFO,
12448 FL("status = %d, already disconnected"),
12449 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012450
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012451 }
12452 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012453 {
12454 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012455 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012456 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012457 result = -EINVAL;
12458 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012459 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012460 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012461 &pAdapter->disconnect_comp_var,
12462 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012463 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012464 {
12465 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012466 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012467 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012468 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012469 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012470 {
12471 hddLog(VOS_TRACE_LEVEL_ERROR,
12472 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012473 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012474 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012475disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012476 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12477 FL("Set HDD connState to eConnectionState_NotConnected"));
12478 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
12479
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012480 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012481 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012482}
12483
12484
12485/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012486 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070012487 * This function is used to issue a disconnect request to SME
12488 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012489static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012490 struct net_device *dev,
12491 u16 reason
12492 )
12493{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012494 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012495 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012496 tCsrRoamProfile *pRoamProfile;
12497 hdd_station_ctx_t *pHddStaCtx;
12498 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012499#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012500 tANI_U8 staIdx;
12501#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012502
Jeff Johnson295189b2012-06-20 16:38:30 -070012503 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012504
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012505 if (!pAdapter) {
12506 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
12507 return -EINVAL;
12508 }
12509
12510 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12511 if (!pHddStaCtx) {
12512 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
12513 return -EINVAL;
12514 }
12515
12516 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12517 status = wlan_hdd_validate_context(pHddCtx);
12518 if (0 != status)
12519 {
12520 return status;
12521 }
12522
12523 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
12524
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012525 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12526 TRACE_CODE_HDD_CFG80211_DISCONNECT,
12527 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012528 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
12529 __func__, hdd_device_modetoString(pAdapter->device_mode),
12530 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012531
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012532 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
12533 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070012534
Jeff Johnson295189b2012-06-20 16:38:30 -070012535 if (NULL != pRoamProfile)
12536 {
12537 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012538 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
12539 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070012540 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012541 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070012542 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012543 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012544 switch(reason)
12545 {
12546 case WLAN_REASON_MIC_FAILURE:
12547 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
12548 break;
12549
12550 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
12551 case WLAN_REASON_DISASSOC_AP_BUSY:
12552 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
12553 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
12554 break;
12555
12556 case WLAN_REASON_PREV_AUTH_NOT_VALID:
12557 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053012558 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070012559 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
12560 break;
12561
Jeff Johnson295189b2012-06-20 16:38:30 -070012562 default:
12563 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
12564 break;
12565 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012566 pScanInfo = &pHddCtx->scan_info;
12567 if (pScanInfo->mScanPending)
12568 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012569 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012570 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012571 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012572 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012573 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012574
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012575#ifdef FEATURE_WLAN_TDLS
12576 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012577 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012578 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012579 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
12580 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012581 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012582 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012583 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012584 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012585 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012586 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012587 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012588 status = sme_DeleteTdlsPeerSta(
12589 WLAN_HDD_GET_HAL_CTX(pAdapter),
12590 pAdapter->sessionId,
12591 mac);
12592 if (status != eHAL_STATUS_SUCCESS) {
12593 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
12594 return -EPERM;
12595 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012596 }
12597 }
12598#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012599 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012600 status = wlan_hdd_disconnect(pAdapter, reasonCode);
12601 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070012602 {
12603 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012604 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012605 __func__, (int)status );
12606 return -EINVAL;
12607 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012608 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012609 else
12610 {
12611 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
12612 "called while in %d state", __func__,
12613 pHddStaCtx->conn_info.connState);
12614 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012615 }
12616 else
12617 {
12618 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
12619 }
12620
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012621 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012622 return status;
12623}
12624
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012625static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
12626 struct net_device *dev,
12627 u16 reason
12628 )
12629{
12630 int ret;
12631 vos_ssr_protect(__func__);
12632 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
12633 vos_ssr_unprotect(__func__);
12634
12635 return ret;
12636}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012637
Jeff Johnson295189b2012-06-20 16:38:30 -070012638/*
12639 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012640 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012641 * settings in IBSS mode.
12642 */
12643static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012644 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012645 struct cfg80211_ibss_params *params
12646 )
12647{
12648 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012649 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012650 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12651 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012652
Jeff Johnson295189b2012-06-20 16:38:30 -070012653 ENTER();
12654
12655 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070012656 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070012657
12658 if (params->ie_len && ( NULL != params->ie) )
12659 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012660 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12661 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012662 {
12663 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12664 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12665 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012666 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012667 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012668 tDot11fIEWPA dot11WPAIE;
12669 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012670 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012671
Wilson Yang00256342013-10-10 23:13:38 -070012672 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012673 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12674 params->ie_len, DOT11F_EID_WPA);
12675 if ( NULL != ie )
12676 {
12677 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12678 // Unpack the WPA IE
12679 //Skip past the EID byte and length byte - and four byte WiFi OUI
12680 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
12681 &ie[2+4],
12682 ie[1] - 4,
12683 &dot11WPAIE);
12684 /*Extract the multicast cipher, the encType for unicast
12685 cipher for wpa-none is none*/
12686 encryptionType =
12687 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
12688 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012689 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012690
Jeff Johnson295189b2012-06-20 16:38:30 -070012691 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
12692
12693 if (0 > status)
12694 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012695 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012696 __func__);
12697 return status;
12698 }
12699 }
12700
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012701 pWextState->roamProfile.AuthType.authType[0] =
12702 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012703 eCSR_AUTH_TYPE_OPEN_SYSTEM;
12704
12705 if (params->privacy)
12706 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012707 /* Security enabled IBSS, At this time there is no information available
12708 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070012709 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012710 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070012711 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012712 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070012713 *enable privacy bit in beacons */
12714
12715 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12716 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012717 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
12718 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070012719 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12720 pWextState->roamProfile.EncryptionType.numEntries = 1;
12721 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070012722 return status;
12723}
12724
12725/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012726 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012727 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012728 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012729static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012730 struct net_device *dev,
12731 struct cfg80211_ibss_params *params
12732 )
12733{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012734 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012735 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12736 tCsrRoamProfile *pRoamProfile;
12737 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012738 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12739 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012740 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070012741
12742 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012743
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012744 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12745 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
12746 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012747 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012748 "%s: device_mode = %s (%d)", __func__,
12749 hdd_device_modetoString(pAdapter->device_mode),
12750 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012751
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012752 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012753 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012754 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012755 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012756 }
12757
12758 if (NULL == pWextState)
12759 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012760 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012761 __func__);
12762 return -EIO;
12763 }
12764
Agarwal Ashish51325b52014-06-16 16:50:49 +053012765 if (vos_max_concurrent_connections_reached()) {
12766 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12767 return -ECONNREFUSED;
12768 }
12769
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012770 /*Try disconnecting if already in connected state*/
12771 status = wlan_hdd_try_disconnect(pAdapter);
12772 if ( 0 > status)
12773 {
12774 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12775 " IBSS connection"));
12776 return -EALREADY;
12777 }
12778
Jeff Johnson295189b2012-06-20 16:38:30 -070012779 pRoamProfile = &pWextState->roamProfile;
12780
12781 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
12782 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012783 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012784 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012785 return -EINVAL;
12786 }
12787
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012788 /* BSSID is provided by upper layers hence no need to AUTO generate */
12789 if (NULL != params->bssid) {
12790 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12791 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
12792 hddLog (VOS_TRACE_LEVEL_ERROR,
12793 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12794 return -EIO;
12795 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012796 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012797 }
krunal sonie9002db2013-11-25 14:24:17 -080012798 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
12799 {
12800 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12801 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
12802 {
12803 hddLog (VOS_TRACE_LEVEL_ERROR,
12804 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12805 return -EIO;
12806 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012807
12808 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080012809 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012810 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080012811 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012812
Jeff Johnson295189b2012-06-20 16:38:30 -070012813 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070012814 if (NULL !=
12815#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12816 params->chandef.chan)
12817#else
12818 params->channel)
12819#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012820 {
12821 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012822 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12823 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
12824 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12825 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012826
12827 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012828 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070012829 ieee80211_frequency_to_channel(
12830#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12831 params->chandef.chan->center_freq);
12832#else
12833 params->channel->center_freq);
12834#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012835
12836 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12837 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070012838 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012839 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
12840 __func__);
12841 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070012842 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012843
12844 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012845 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012846 if (channelNum == validChan[indx])
12847 {
12848 break;
12849 }
12850 }
12851 if (indx >= numChans)
12852 {
12853 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012854 __func__, channelNum);
12855 return -EINVAL;
12856 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012857 /* Set the Operational Channel */
12858 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
12859 channelNum);
12860 pRoamProfile->ChannelInfo.numOfChannels = 1;
12861 pHddStaCtx->conn_info.operationChannel = channelNum;
12862 pRoamProfile->ChannelInfo.ChannelList =
12863 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070012864 }
12865
12866 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012867 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070012868 if (status < 0)
12869 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012870 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070012871 __func__);
12872 return status;
12873 }
12874
12875 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012876 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012877 params->ssid_len, params->bssid,
12878 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070012879
12880 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012881 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012882
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012883 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012884 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012885}
12886
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012887static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
12888 struct net_device *dev,
12889 struct cfg80211_ibss_params *params
12890 )
12891{
12892 int ret = 0;
12893
12894 vos_ssr_protect(__func__);
12895 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
12896 vos_ssr_unprotect(__func__);
12897
12898 return ret;
12899}
12900
Jeff Johnson295189b2012-06-20 16:38:30 -070012901/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012902 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012903 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012904 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012905static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012906 struct net_device *dev
12907 )
12908{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012909 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012910 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12911 tCsrRoamProfile *pRoamProfile;
12912 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012913 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012914
12915 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012916
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012917 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12918 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
12919 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012920 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012921 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012922 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012923 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012924 }
12925
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012926 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
12927 hdd_device_modetoString(pAdapter->device_mode),
12928 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012929 if (NULL == pWextState)
12930 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012931 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012932 __func__);
12933 return -EIO;
12934 }
12935
12936 pRoamProfile = &pWextState->roamProfile;
12937
12938 /* Issue disconnect only if interface type is set to IBSS */
12939 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
12940 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012941 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070012942 __func__);
12943 return -EINVAL;
12944 }
12945
12946 /* Issue Disconnect request */
12947 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12948 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12949 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
12950
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012951 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012952 return 0;
12953}
12954
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012955static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
12956 struct net_device *dev
12957 )
12958{
12959 int ret = 0;
12960
12961 vos_ssr_protect(__func__);
12962 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
12963 vos_ssr_unprotect(__func__);
12964
12965 return ret;
12966}
12967
Jeff Johnson295189b2012-06-20 16:38:30 -070012968/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012969 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070012970 * This function is used to set the phy parameters
12971 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
12972 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012973static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012974 u32 changed)
12975{
12976 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
12977 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012978 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012979
12980 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012981
12982 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012983 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
12984 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012985
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012986 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012987 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012988 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012989 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012990 }
12991
Jeff Johnson295189b2012-06-20 16:38:30 -070012992 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
12993 {
12994 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
12995 WNI_CFG_RTS_THRESHOLD_STAMAX :
12996 wiphy->rts_threshold;
12997
12998 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012999 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070013000 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013001 hddLog(VOS_TRACE_LEVEL_ERROR,
13002 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013003 __func__, rts_threshold);
13004 return -EINVAL;
13005 }
13006
13007 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
13008 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013009 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013010 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013011 hddLog(VOS_TRACE_LEVEL_ERROR,
13012 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013013 __func__, rts_threshold);
13014 return -EIO;
13015 }
13016
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013017 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013018 rts_threshold);
13019 }
13020
13021 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
13022 {
13023 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
13024 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
13025 wiphy->frag_threshold;
13026
13027 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013028 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013029 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013030 hddLog(VOS_TRACE_LEVEL_ERROR,
13031 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013032 frag_threshold);
13033 return -EINVAL;
13034 }
13035
13036 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
13037 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013038 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013039 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013040 hddLog(VOS_TRACE_LEVEL_ERROR,
13041 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013042 __func__, frag_threshold);
13043 return -EIO;
13044 }
13045
13046 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
13047 frag_threshold);
13048 }
13049
13050 if ((changed & WIPHY_PARAM_RETRY_SHORT)
13051 || (changed & WIPHY_PARAM_RETRY_LONG))
13052 {
13053 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
13054 wiphy->retry_short :
13055 wiphy->retry_long;
13056
13057 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
13058 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
13059 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013060 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013061 __func__, retry_value);
13062 return -EINVAL;
13063 }
13064
13065 if (changed & WIPHY_PARAM_RETRY_SHORT)
13066 {
13067 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
13068 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013069 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013070 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013071 hddLog(VOS_TRACE_LEVEL_ERROR,
13072 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013073 __func__, retry_value);
13074 return -EIO;
13075 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013076 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013077 __func__, retry_value);
13078 }
13079 else if (changed & WIPHY_PARAM_RETRY_SHORT)
13080 {
13081 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
13082 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013083 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013084 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013085 hddLog(VOS_TRACE_LEVEL_ERROR,
13086 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013087 __func__, retry_value);
13088 return -EIO;
13089 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013090 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013091 __func__, retry_value);
13092 }
13093 }
13094
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013095 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013096 return 0;
13097}
13098
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013099static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
13100 u32 changed)
13101{
13102 int ret;
13103
13104 vos_ssr_protect(__func__);
13105 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
13106 vos_ssr_unprotect(__func__);
13107
13108 return ret;
13109}
13110
Jeff Johnson295189b2012-06-20 16:38:30 -070013111/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013112 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013113 * This function is used to set the txpower
13114 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013115static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013116#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13117 struct wireless_dev *wdev,
13118#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013119#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013120 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013121#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013122 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013123#endif
13124 int dbm)
13125{
13126 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013127 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013128 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13129 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013130 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013131
13132 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013133
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013134 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13135 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
13136 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013137 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013138 if (0 != status)
13139 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013140 return status;
13141 }
13142
13143 hHal = pHddCtx->hHal;
13144
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013145 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
13146 dbm, ccmCfgSetCallback,
13147 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013148 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013149 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013150 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
13151 return -EIO;
13152 }
13153
13154 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
13155 dbm);
13156
13157 switch(type)
13158 {
13159 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
13160 /* Fall through */
13161 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
13162 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
13163 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013164 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
13165 __func__);
13166 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013167 }
13168 break;
13169 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013170 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070013171 __func__);
13172 return -EOPNOTSUPP;
13173 break;
13174 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013175 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
13176 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070013177 return -EIO;
13178 }
13179
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013180 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013181 return 0;
13182}
13183
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013184static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
13185#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13186 struct wireless_dev *wdev,
13187#endif
13188#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13189 enum tx_power_setting type,
13190#else
13191 enum nl80211_tx_power_setting type,
13192#endif
13193 int dbm)
13194{
13195 int ret;
13196 vos_ssr_protect(__func__);
13197 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
13198#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13199 wdev,
13200#endif
13201#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13202 type,
13203#else
13204 type,
13205#endif
13206 dbm);
13207 vos_ssr_unprotect(__func__);
13208
13209 return ret;
13210}
13211
Jeff Johnson295189b2012-06-20 16:38:30 -070013212/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013213 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013214 * This function is used to read the txpower
13215 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013216static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013217#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13218 struct wireless_dev *wdev,
13219#endif
13220 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070013221{
13222
13223 hdd_adapter_t *pAdapter;
13224 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013225 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013226
Jeff Johnsone7245742012-09-05 17:12:55 -070013227 ENTER();
13228
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013229 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013230 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013231 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013232 *dbm = 0;
13233 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013234 }
13235
Jeff Johnson295189b2012-06-20 16:38:30 -070013236 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
13237 if (NULL == pAdapter)
13238 {
13239 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
13240 return -ENOENT;
13241 }
13242
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053013243 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13244 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
13245 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070013246 wlan_hdd_get_classAstats(pAdapter);
13247 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
13248
Jeff Johnsone7245742012-09-05 17:12:55 -070013249 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013250 return 0;
13251}
13252
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013253static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
13254#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13255 struct wireless_dev *wdev,
13256#endif
13257 int *dbm)
13258{
13259 int ret;
13260
13261 vos_ssr_protect(__func__);
13262 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
13263#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13264 wdev,
13265#endif
13266 dbm);
13267 vos_ssr_unprotect(__func__);
13268
13269 return ret;
13270}
13271
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013272static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013273#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13274 const u8* mac,
13275#else
13276 u8* mac,
13277#endif
13278 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070013279{
13280 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13281 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13282 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053013283 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070013284
13285 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
13286 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070013287
13288 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
13289 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
13290 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
13291 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
13292 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
13293 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
13294 tANI_U16 maxRate = 0;
13295 tANI_U16 myRate;
13296 tANI_U16 currentRate = 0;
13297 tANI_U8 maxSpeedMCS = 0;
13298 tANI_U8 maxMCSIdx = 0;
13299 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053013300 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013301 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013302 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013303
Leo Chang6f8870f2013-03-26 18:11:36 -070013304#ifdef WLAN_FEATURE_11AC
13305 tANI_U32 vht_mcs_map;
13306 eDataRate11ACMaxMcs vhtMaxMcs;
13307#endif /* WLAN_FEATURE_11AC */
13308
Jeff Johnsone7245742012-09-05 17:12:55 -070013309 ENTER();
13310
Jeff Johnson295189b2012-06-20 16:38:30 -070013311 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
13312 (0 == ssidlen))
13313 {
13314 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
13315 " Invalid ssidlen, %d", __func__, ssidlen);
13316 /*To keep GUI happy*/
13317 return 0;
13318 }
13319
Mukul Sharma811205f2014-07-09 21:07:30 +053013320 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
13321 {
13322 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13323 "%s: Roaming in progress, so unable to proceed this request", __func__);
13324 return 0;
13325 }
13326
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013327 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013328 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013329 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013330 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013331 }
13332
Jeff Johnson295189b2012-06-20 16:38:30 -070013333
Kiet Lam3b17fc82013-09-27 05:24:08 +053013334 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
13335 sinfo->filled |= STATION_INFO_SIGNAL;
13336
c_hpothu09f19542014-05-30 21:53:31 +053013337 wlan_hdd_get_station_stats(pAdapter);
13338 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
13339
13340 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053013341 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
13342 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053013343 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053013344 {
13345 rate_flags = pAdapter->maxRateFlags;
13346 }
c_hpothu44ff4e02014-05-08 00:13:57 +053013347
Jeff Johnson295189b2012-06-20 16:38:30 -070013348 //convert to the UI units of 100kbps
13349 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
13350
13351#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070013352 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 -070013353 sinfo->signal,
13354 pCfg->reportMaxLinkSpeed,
13355 myRate,
13356 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013357 (int) pCfg->linkSpeedRssiMid,
13358 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070013359 (int) rate_flags,
13360 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013361#endif //LINKSPEED_DEBUG_ENABLED
13362
13363 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
13364 {
13365 // we do not want to necessarily report the current speed
13366 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
13367 {
13368 // report the max possible speed
13369 rssidx = 0;
13370 }
13371 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
13372 {
13373 // report the max possible speed with RSSI scaling
13374 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
13375 {
13376 // report the max possible speed
13377 rssidx = 0;
13378 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013379 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070013380 {
13381 // report middle speed
13382 rssidx = 1;
13383 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013384 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
13385 {
13386 // report middle speed
13387 rssidx = 2;
13388 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013389 else
13390 {
13391 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013392 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070013393 }
13394 }
13395 else
13396 {
13397 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
13398 hddLog(VOS_TRACE_LEVEL_ERROR,
13399 "%s: Invalid value for reportMaxLinkSpeed: %u",
13400 __func__, pCfg->reportMaxLinkSpeed);
13401 rssidx = 0;
13402 }
13403
13404 maxRate = 0;
13405
13406 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013407 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
13408 OperationalRates, &ORLeng))
13409 {
13410 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13411 /*To keep GUI happy*/
13412 return 0;
13413 }
13414
Jeff Johnson295189b2012-06-20 16:38:30 -070013415 for (i = 0; i < ORLeng; i++)
13416 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013417 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013418 {
13419 /* Validate Rate Set */
13420 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
13421 {
13422 currentRate = supported_data_rate[j].supported_rate[rssidx];
13423 break;
13424 }
13425 }
13426 /* Update MAX rate */
13427 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13428 }
13429
13430 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013431 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
13432 ExtendedRates, &ERLeng))
13433 {
13434 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13435 /*To keep GUI happy*/
13436 return 0;
13437 }
13438
Jeff Johnson295189b2012-06-20 16:38:30 -070013439 for (i = 0; i < ERLeng; i++)
13440 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013441 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013442 {
13443 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
13444 {
13445 currentRate = supported_data_rate[j].supported_rate[rssidx];
13446 break;
13447 }
13448 }
13449 /* Update MAX rate */
13450 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13451 }
c_hpothu79aab322014-07-14 21:11:01 +053013452
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013453 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053013454 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013455 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053013456 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070013457 {
c_hpothu79aab322014-07-14 21:11:01 +053013458 if (rate_flags & eHAL_TX_RATE_VHT80)
13459 mode = 2;
13460 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
13461 mode = 1;
13462 else
13463 mode = 0;
13464
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013465 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
13466 MCSRates, &MCSLeng))
13467 {
13468 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13469 /*To keep GUI happy*/
13470 return 0;
13471 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013472 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070013473#ifdef WLAN_FEATURE_11AC
13474 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013475 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070013476 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013477 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013478 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070013479 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070013480 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013481 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013482 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013483 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070013484 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013485 maxMCSIdx = 7;
13486 }
13487 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
13488 {
13489 maxMCSIdx = 8;
13490 }
13491 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
13492 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013493 //VHT20 is supporting 0~8
13494 if (rate_flags & eHAL_TX_RATE_VHT20)
13495 maxMCSIdx = 8;
13496 else
13497 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070013498 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013499
c_hpothu79aab322014-07-14 21:11:01 +053013500 if (0 != rssidx)/*check for scaled */
13501 {
13502 //get middle rate MCS index if rssi=1/2
13503 for (i=0; i <= maxMCSIdx; i++)
13504 {
13505 if (sinfo->signal <= rssiMcsTbl[mode][i])
13506 {
13507 maxMCSIdx = i;
13508 break;
13509 }
13510 }
13511 }
13512
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013513 if (rate_flags & eHAL_TX_RATE_VHT80)
13514 {
13515 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
13516 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
13517 }
13518 else if (rate_flags & eHAL_TX_RATE_VHT40)
13519 {
13520 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
13521 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
13522 }
13523 else if (rate_flags & eHAL_TX_RATE_VHT20)
13524 {
13525 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
13526 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
13527 }
13528
Leo Chang6f8870f2013-03-26 18:11:36 -070013529 maxSpeedMCS = 1;
13530 if (currentRate > maxRate)
13531 {
13532 maxRate = currentRate;
13533 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013534
Leo Chang6f8870f2013-03-26 18:11:36 -070013535 }
13536 else
13537#endif /* WLAN_FEATURE_11AC */
13538 {
13539 if (rate_flags & eHAL_TX_RATE_HT40)
13540 {
13541 rateFlag |= 1;
13542 }
13543 if (rate_flags & eHAL_TX_RATE_SGI)
13544 {
13545 rateFlag |= 2;
13546 }
13547
Girish Gowli01abcee2014-07-31 20:18:55 +053013548 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053013549 if (rssidx == 1 || rssidx == 2)
13550 {
13551 //get middle rate MCS index if rssi=1/2
13552 for (i=0; i <= 7; i++)
13553 {
13554 if (sinfo->signal <= rssiMcsTbl[mode][i])
13555 {
13556 temp = i+1;
13557 break;
13558 }
13559 }
13560 }
c_hpothu79aab322014-07-14 21:11:01 +053013561
13562 for (i = 0; i < MCSLeng; i++)
13563 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013564 for (j = 0; j < temp; j++)
13565 {
13566 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
13567 {
13568 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053013569 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013570 break;
13571 }
13572 }
13573 if ((j < temp) && (currentRate > maxRate))
13574 {
13575 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070013576 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013577 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053013578 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013579 }
13580 }
13581
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013582 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
13583 {
13584 maxRate = myRate;
13585 maxSpeedMCS = 1;
13586 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13587 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013588 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053013589 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070013590 {
13591 maxRate = myRate;
13592 if (rate_flags & eHAL_TX_RATE_LEGACY)
13593 {
13594 maxSpeedMCS = 0;
13595 }
13596 else
13597 {
13598 maxSpeedMCS = 1;
13599 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13600 }
13601 }
13602
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013603 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070013604 {
13605 sinfo->txrate.legacy = maxRate;
13606#ifdef LINKSPEED_DEBUG_ENABLED
13607 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
13608#endif //LINKSPEED_DEBUG_ENABLED
13609 }
13610 else
13611 {
13612 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070013613#ifdef WLAN_FEATURE_11AC
13614 sinfo->txrate.nss = 1;
13615 if (rate_flags & eHAL_TX_RATE_VHT80)
13616 {
13617 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013618 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070013619 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013620 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070013621 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013622 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13623 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13624 }
13625 else if (rate_flags & eHAL_TX_RATE_VHT20)
13626 {
13627 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13628 }
13629#endif /* WLAN_FEATURE_11AC */
13630 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
13631 {
13632 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13633 if (rate_flags & eHAL_TX_RATE_HT40)
13634 {
13635 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13636 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013637 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013638 if (rate_flags & eHAL_TX_RATE_SGI)
13639 {
13640 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13641 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013642
Jeff Johnson295189b2012-06-20 16:38:30 -070013643#ifdef LINKSPEED_DEBUG_ENABLED
13644 pr_info("Reporting MCS rate %d flags %x\n",
13645 sinfo->txrate.mcs,
13646 sinfo->txrate.flags );
13647#endif //LINKSPEED_DEBUG_ENABLED
13648 }
13649 }
13650 else
13651 {
13652 // report current rate instead of max rate
13653
13654 if (rate_flags & eHAL_TX_RATE_LEGACY)
13655 {
13656 //provide to the UI in units of 100kbps
13657 sinfo->txrate.legacy = myRate;
13658#ifdef LINKSPEED_DEBUG_ENABLED
13659 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
13660#endif //LINKSPEED_DEBUG_ENABLED
13661 }
13662 else
13663 {
13664 //must be MCS
13665 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013666#ifdef WLAN_FEATURE_11AC
13667 sinfo->txrate.nss = 1;
13668 if (rate_flags & eHAL_TX_RATE_VHT80)
13669 {
13670 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13671 }
13672 else
13673#endif /* WLAN_FEATURE_11AC */
13674 {
13675 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13676 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013677 if (rate_flags & eHAL_TX_RATE_SGI)
13678 {
13679 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13680 }
13681 if (rate_flags & eHAL_TX_RATE_HT40)
13682 {
13683 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13684 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013685#ifdef WLAN_FEATURE_11AC
13686 else if (rate_flags & eHAL_TX_RATE_VHT80)
13687 {
13688 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
13689 }
13690#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070013691#ifdef LINKSPEED_DEBUG_ENABLED
13692 pr_info("Reporting actual MCS rate %d flags %x\n",
13693 sinfo->txrate.mcs,
13694 sinfo->txrate.flags );
13695#endif //LINKSPEED_DEBUG_ENABLED
13696 }
13697 }
13698 sinfo->filled |= STATION_INFO_TX_BITRATE;
13699
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013700 sinfo->tx_packets =
13701 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
13702 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
13703 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
13704 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
13705
13706 sinfo->tx_retries =
13707 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
13708 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
13709 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
13710 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
13711
13712 sinfo->tx_failed =
13713 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
13714 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
13715 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
13716 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
13717
13718 sinfo->filled |=
13719 STATION_INFO_TX_PACKETS |
13720 STATION_INFO_TX_RETRIES |
13721 STATION_INFO_TX_FAILED;
13722
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013723 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13724 TRACE_CODE_HDD_CFG80211_GET_STA,
13725 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013726 EXIT();
13727 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013728}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013729#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13730static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
13731 const u8* mac, struct station_info *sinfo)
13732#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013733static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
13734 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013735#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013736{
13737 int ret;
13738
13739 vos_ssr_protect(__func__);
13740 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
13741 vos_ssr_unprotect(__func__);
13742
13743 return ret;
13744}
13745
13746static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070013747 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070013748{
13749 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013750 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013751 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013752 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013753
Jeff Johnsone7245742012-09-05 17:12:55 -070013754 ENTER();
13755
Jeff Johnson295189b2012-06-20 16:38:30 -070013756 if (NULL == pAdapter)
13757 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013758 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013759 return -ENODEV;
13760 }
13761
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013762 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13763 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
13764 pAdapter->sessionId, timeout));
13765
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013766 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013767 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013768 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013769 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013770 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013771 }
13772
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013773 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
13774 (TRUE == pHddCtx->hdd_wlan_suspended) &&
13775 (pHddCtx->cfg_ini->fhostArpOffload) &&
13776 (eConnectionState_Associated ==
13777 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13778 {
Amar Singhald53568e2013-09-26 11:03:45 -070013779
13780 hddLog(VOS_TRACE_LEVEL_INFO,
13781 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053013782 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013783 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13784 {
13785 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013786 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013787 __func__, vos_status);
13788 }
13789 }
13790
Jeff Johnson295189b2012-06-20 16:38:30 -070013791 /**The get power cmd from the supplicant gets updated by the nl only
13792 *on successful execution of the function call
13793 *we are oppositely mapped w.r.t mode in the driver
13794 **/
13795 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
13796
13797 if (VOS_STATUS_E_FAILURE == vos_status)
13798 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013799 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13800 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013801 return -EINVAL;
13802 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013803 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013804 return 0;
13805}
13806
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013807static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
13808 struct net_device *dev, bool mode, int timeout)
13809{
13810 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013811
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013812 vos_ssr_protect(__func__);
13813 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
13814 vos_ssr_unprotect(__func__);
13815
13816 return ret;
13817}
Jeff Johnson295189b2012-06-20 16:38:30 -070013818#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013819static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
13820 struct net_device *netdev,
13821 u8 key_index)
13822{
13823 ENTER();
13824 return 0;
13825}
13826
Jeff Johnson295189b2012-06-20 16:38:30 -070013827static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013828 struct net_device *netdev,
13829 u8 key_index)
13830{
13831 int ret;
13832 vos_ssr_protect(__func__);
13833 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
13834 vos_ssr_unprotect(__func__);
13835 return ret;
13836}
13837#endif //LINUX_VERSION_CODE
13838
13839#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13840static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13841 struct net_device *dev,
13842 struct ieee80211_txq_params *params)
13843{
13844 ENTER();
13845 return 0;
13846}
13847#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13848static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13849 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013850{
Jeff Johnsone7245742012-09-05 17:12:55 -070013851 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013852 return 0;
13853}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013854#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070013855
13856#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13857static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013858 struct net_device *dev,
13859 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013860{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013861 int ret;
13862
13863 vos_ssr_protect(__func__);
13864 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
13865 vos_ssr_unprotect(__func__);
13866 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013867}
13868#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13869static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
13870 struct ieee80211_txq_params *params)
13871{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013872 int ret;
13873
13874 vos_ssr_protect(__func__);
13875 ret = __wlan_hdd_set_txq_params(wiphy, params);
13876 vos_ssr_unprotect(__func__);
13877 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013878}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013879#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013880
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013881static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013882 struct net_device *dev,
13883 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070013884{
13885 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013886 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013887 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013888 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013889 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013890 v_CONTEXT_t pVosContext = NULL;
13891 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013892
Jeff Johnsone7245742012-09-05 17:12:55 -070013893 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013894
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013895 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070013896 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013897 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013898 return -EINVAL;
13899 }
13900
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013901 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13902 TRACE_CODE_HDD_CFG80211_DEL_STA,
13903 pAdapter->sessionId, pAdapter->device_mode));
13904
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013905 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13906 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013907 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013908 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013909 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013910 }
13911
Jeff Johnson295189b2012-06-20 16:38:30 -070013912 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013913 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013914 )
13915 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013916 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13917 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13918 if(pSapCtx == NULL){
13919 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13920 FL("psapCtx is NULL"));
13921 return -ENOENT;
13922 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013923 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013924 {
13925 v_U16_t i;
13926 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
13927 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013928 if ((pSapCtx->aStaInfo[i].isUsed) &&
13929 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070013930 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013931 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013932 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013933 ETHER_ADDR_LEN);
13934
Jeff Johnson295189b2012-06-20 16:38:30 -070013935 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013936 "%s: Delete STA with MAC::"
13937 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013938 __func__,
13939 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
13940 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070013941 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013942 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013943 }
13944 }
13945 }
13946 else
13947 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013948
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013949 vos_status = hdd_softap_GetStaId(pAdapter,
13950 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013951 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13952 {
13953 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013954 "%s: Skip this DEL STA as this is not used::"
13955 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013956 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013957 return -ENOENT;
13958 }
13959
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013960 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013961 {
13962 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013963 "%s: Skip this DEL STA as deauth is in progress::"
13964 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013965 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013966 return -ENOENT;
13967 }
13968
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013969 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013970
Jeff Johnson295189b2012-06-20 16:38:30 -070013971 hddLog(VOS_TRACE_LEVEL_INFO,
13972 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013973 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013974 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013975 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013976
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013977 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013978 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13979 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013980 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013981 hddLog(VOS_TRACE_LEVEL_INFO,
13982 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013983 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013984 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013985 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013986 return -ENOENT;
13987 }
13988
Jeff Johnson295189b2012-06-20 16:38:30 -070013989 }
13990 }
13991
13992 EXIT();
13993
13994 return 0;
13995}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013996
13997#ifdef CFG80211_DEL_STA_V2
13998static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
13999 struct net_device *dev,
14000 struct station_del_parameters *param)
14001#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014002#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14003static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14004 struct net_device *dev, const u8 *mac)
14005#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014006static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14007 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014008#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014009#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014010{
14011 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014012 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070014013
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014014 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014015
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014016#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014017 if (NULL == param) {
14018 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014019 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014020 return -EINVAL;
14021 }
14022
14023 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
14024 param->subtype, &delStaParams);
14025
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014026#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053014027 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014028 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014029#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014030 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
14031
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014032 vos_ssr_unprotect(__func__);
14033
14034 return ret;
14035}
14036
14037static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014038 struct net_device *dev,
14039#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14040 const u8 *mac,
14041#else
14042 u8 *mac,
14043#endif
14044 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014045{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014046 hdd_adapter_t *pAdapter;
14047 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014048 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014049#ifdef FEATURE_WLAN_TDLS
14050 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014051
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014052 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014053
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014054 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14055 if (NULL == pAdapter)
14056 {
14057 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14058 "%s: Adapter is NULL",__func__);
14059 return -EINVAL;
14060 }
14061 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14062 status = wlan_hdd_validate_context(pHddCtx);
14063 if (0 != status)
14064 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014065 return status;
14066 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014067
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014068 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14069 TRACE_CODE_HDD_CFG80211_ADD_STA,
14070 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014071 mask = params->sta_flags_mask;
14072
14073 set = params->sta_flags_set;
14074
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014075 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014076 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
14077 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014078
14079 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
14080 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014081 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014082 }
14083 }
14084#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014085 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014086 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014087}
14088
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014089#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14090static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14091 struct net_device *dev, const u8 *mac,
14092 struct station_parameters *params)
14093#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014094static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14095 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014096#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014097{
14098 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014099
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014100 vos_ssr_protect(__func__);
14101 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
14102 vos_ssr_unprotect(__func__);
14103
14104 return ret;
14105}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014106#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070014107
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014108static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070014109 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014110{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014111 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14112 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014113 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014114 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014115 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014116 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070014117
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014118 ENTER();
14119
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014120 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014121 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014122 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014123 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014124 return -EINVAL;
14125 }
14126
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014127 if (!pmksa) {
14128 hddLog(LOGE, FL("pmksa is NULL"));
14129 return -EINVAL;
14130 }
14131
14132 if (!pmksa->bssid || !pmksa->pmkid) {
14133 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
14134 pmksa->bssid, pmksa->pmkid);
14135 return -EINVAL;
14136 }
14137
14138 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
14139 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14140
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014141 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14142 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014143 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014144 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014145 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014146 }
14147
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014148 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014149 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14150
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014151 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
14152 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014153
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014154 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014155 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014156 &pmk_id, 1, FALSE);
14157
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014158 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14159 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
14160 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014161
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014162 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014163 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014164}
14165
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014166static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
14167 struct cfg80211_pmksa *pmksa)
14168{
14169 int ret;
14170
14171 vos_ssr_protect(__func__);
14172 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
14173 vos_ssr_unprotect(__func__);
14174
14175 return ret;
14176}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014177
Wilson Yang6507c4e2013-10-01 20:11:19 -070014178
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014179static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070014180 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014181{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014182 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14183 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014184 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014185 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014186
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014187 ENTER();
14188
Wilson Yang6507c4e2013-10-01 20:11:19 -070014189 /* Validate pAdapter */
14190 if (NULL == pAdapter)
14191 {
14192 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
14193 return -EINVAL;
14194 }
14195
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014196 if (!pmksa) {
14197 hddLog(LOGE, FL("pmksa is NULL"));
14198 return -EINVAL;
14199 }
14200
14201 if (!pmksa->bssid) {
14202 hddLog(LOGE, FL("pmksa->bssid is NULL"));
14203 return -EINVAL;
14204 }
14205
Kiet Lam98c46a12014-10-31 15:34:57 -070014206 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
14207 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14208
Wilson Yang6507c4e2013-10-01 20:11:19 -070014209 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14210 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014211 if (0 != status)
14212 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014213 return status;
14214 }
14215
14216 /*Retrieve halHandle*/
14217 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14218
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014219 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14220 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
14221 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014222 /* Delete the PMKID CSR cache */
14223 if (eHAL_STATUS_SUCCESS !=
14224 sme_RoamDelPMKIDfromCache(halHandle,
14225 pAdapter->sessionId, pmksa->bssid, FALSE)) {
14226 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
14227 MAC_ADDR_ARRAY(pmksa->bssid));
14228 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014229 }
14230
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014231 EXIT();
14232 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014233}
14234
Wilson Yang6507c4e2013-10-01 20:11:19 -070014235
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014236static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
14237 struct cfg80211_pmksa *pmksa)
14238{
14239 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014240
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014241 vos_ssr_protect(__func__);
14242 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
14243 vos_ssr_unprotect(__func__);
14244
14245 return ret;
14246
14247}
14248
14249static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014250{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014251 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14252 tHalHandle halHandle;
14253 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014254 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014255
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014256 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070014257
14258 /* Validate pAdapter */
14259 if (NULL == pAdapter)
14260 {
14261 hddLog(VOS_TRACE_LEVEL_ERROR,
14262 "%s: Invalid Adapter" ,__func__);
14263 return -EINVAL;
14264 }
14265
14266 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14267 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014268 if (0 != status)
14269 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014270 return status;
14271 }
14272
14273 /*Retrieve halHandle*/
14274 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14275
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014276 /* Flush the PMKID cache in CSR */
14277 if (eHAL_STATUS_SUCCESS !=
14278 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
14279 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
14280 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014281 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014282 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080014283 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014284}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014285
14286static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
14287{
14288 int ret;
14289
14290 vos_ssr_protect(__func__);
14291 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
14292 vos_ssr_unprotect(__func__);
14293
14294 return ret;
14295}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014296#endif
14297
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014298#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014299static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14300 struct net_device *dev,
14301 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014302{
14303 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14304 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014305 hdd_context_t *pHddCtx;
14306 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014307
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014308 ENTER();
14309
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014310 if (NULL == pAdapter)
14311 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014312 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014313 return -ENODEV;
14314 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014315 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14316 ret = wlan_hdd_validate_context(pHddCtx);
14317 if (0 != ret)
14318 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014319 return ret;
14320 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014321 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014322 if (NULL == pHddStaCtx)
14323 {
14324 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
14325 return -EINVAL;
14326 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014327
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014328 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14329 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
14330 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014331 // Added for debug on reception of Re-assoc Req.
14332 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
14333 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014334 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014335 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080014336 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014337 }
14338
14339#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080014340 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014341 ftie->ie_len);
14342#endif
14343
14344 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014345 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
14346 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014347 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014348
14349 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014350 return 0;
14351}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014352
14353static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14354 struct net_device *dev,
14355 struct cfg80211_update_ft_ies_params *ftie)
14356{
14357 int ret;
14358
14359 vos_ssr_protect(__func__);
14360 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
14361 vos_ssr_unprotect(__func__);
14362
14363 return ret;
14364}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014365#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014366
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014367#ifdef FEATURE_WLAN_SCAN_PNO
14368
14369void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
14370 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
14371{
14372 int ret;
14373 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
14374 hdd_context_t *pHddCtx;
14375
Nirav Shah80830bf2013-12-31 16:35:12 +053014376 ENTER();
14377
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014378 if (NULL == pAdapter)
14379 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014380 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014381 "%s: HDD adapter is Null", __func__);
14382 return ;
14383 }
14384
14385 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14386 if (NULL == pHddCtx)
14387 {
14388 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14389 "%s: HDD context is Null!!!", __func__);
14390 return ;
14391 }
14392
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014393 spin_lock(&pHddCtx->schedScan_lock);
14394 if (TRUE == pHddCtx->isWiphySuspended)
14395 {
14396 pHddCtx->isSchedScanUpdatePending = TRUE;
14397 spin_unlock(&pHddCtx->schedScan_lock);
14398 hddLog(VOS_TRACE_LEVEL_INFO,
14399 "%s: Update cfg80211 scan database after it resume", __func__);
14400 return ;
14401 }
14402 spin_unlock(&pHddCtx->schedScan_lock);
14403
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014404 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
14405
14406 if (0 > ret)
14407 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
14408
14409 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014410 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14411 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014412}
14413
14414/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014415 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014416 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014417 */
14418static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
14419{
14420 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14421 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014422 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014423 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14424 int status = 0;
14425 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
14426
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014427 /* The current firmware design does not allow PNO during any
14428 * active sessions. Hence, determine the active sessions
14429 * and return a failure.
14430 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014431 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
14432 {
14433 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014434 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014435
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014436 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
14437 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
14438 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
14439 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
14440 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053014441 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014442 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014443 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014444 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014445 }
14446 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14447 pAdapterNode = pNext;
14448 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014449 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014450}
14451
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014452void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
14453{
14454 hdd_adapter_t *pAdapter = callbackContext;
14455 hdd_context_t *pHddCtx;
14456
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014457 ENTER();
14458
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014459 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
14460 {
14461 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14462 FL("Invalid adapter or adapter has invalid magic"));
14463 return;
14464 }
14465
14466 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14467 if (0 != wlan_hdd_validate_context(pHddCtx))
14468 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014469 return;
14470 }
14471
c_hpothub53c45d2014-08-18 16:53:14 +053014472 if (VOS_STATUS_SUCCESS != status)
14473 {
14474 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014475 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053014476 pHddCtx->isPnoEnable = FALSE;
14477 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014478
14479 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
14480 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014481 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014482}
14483
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014484/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014485 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
14486 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014487 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014488static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014489 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14490{
14491 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014492 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014493 hdd_context_t *pHddCtx;
14494 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014495 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053014496 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
14497 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014498 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
14499 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014500 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014501 hdd_config_t *pConfig = NULL;
14502 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014503
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014504 ENTER();
14505
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014506 if (NULL == pAdapter)
14507 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014508 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014509 "%s: HDD adapter is Null", __func__);
14510 return -ENODEV;
14511 }
14512
14513 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014514 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014515
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014516 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014517 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014518 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014519 }
14520
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014521 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014522 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14523 if (NULL == hHal)
14524 {
14525 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14526 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014527 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014528 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014529 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14530 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
14531 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053014532 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014533 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053014534 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014535 {
14536 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14537 "%s: aborting the existing scan is unsuccessfull", __func__);
14538 return -EBUSY;
14539 }
14540
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014541 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014542 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014543 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014544 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014545 return -EBUSY;
14546 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014547
c_hpothu37f21312014-04-09 21:49:54 +053014548 if (TRUE == pHddCtx->isPnoEnable)
14549 {
14550 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14551 FL("already PNO is enabled"));
14552 return -EBUSY;
14553 }
c_hpothu225aa7c2014-10-22 17:45:13 +053014554
14555 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
14556 {
14557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14558 "%s: abort ROC failed ", __func__);
14559 return -EBUSY;
14560 }
14561
c_hpothu37f21312014-04-09 21:49:54 +053014562 pHddCtx->isPnoEnable = TRUE;
14563
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014564 pnoRequest.enable = 1; /*Enable PNO */
14565 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014566
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014567 if (( !pnoRequest.ucNetworksCount ) ||
14568 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014569 {
14570 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014571 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014572 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014573 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014574 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014575 goto error;
14576 }
14577
14578 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
14579 {
14580 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014581 "%s: Incorrect number of channels %d",
14582 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014583 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014584 goto error;
14585 }
14586
14587 /* Framework provides one set of channels(all)
14588 * common for all saved profile */
14589 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
14590 channels_allowed, &num_channels_allowed))
14591 {
14592 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14593 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014594 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014595 goto error;
14596 }
14597 /* Checking each channel against allowed channel list */
14598 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053014599 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014600 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014601 char chList [(request->n_channels*5)+1];
14602 int len;
14603 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014604 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014605 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014606 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014607 if (request->channels[i]->hw_value == channels_allowed[indx])
14608 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014609 if ((!pConfig->enableDFSPnoChnlScan) &&
14610 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
14611 {
14612 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14613 "%s : Dropping DFS channel : %d",
14614 __func__,channels_allowed[indx]);
14615 num_ignore_dfs_ch++;
14616 break;
14617 }
14618
Nirav Shah80830bf2013-12-31 16:35:12 +053014619 valid_ch[num_ch++] = request->channels[i]->hw_value;
14620 len += snprintf(chList+len, 5, "%d ",
14621 request->channels[i]->hw_value);
14622 break ;
14623 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014624 }
14625 }
Nirav Shah80830bf2013-12-31 16:35:12 +053014626 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014627
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014628 /*If all channels are DFS and dropped, then ignore the PNO request*/
14629 if (num_ignore_dfs_ch == request->n_channels)
14630 {
14631 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14632 "%s : All requested channels are DFS channels", __func__);
14633 ret = -EINVAL;
14634 goto error;
14635 }
14636 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014637
14638 pnoRequest.aNetworks =
14639 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14640 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014641 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014642 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14643 FL("failed to allocate memory aNetworks %u"),
14644 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14645 goto error;
14646 }
14647 vos_mem_zero(pnoRequest.aNetworks,
14648 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14649
14650 /* Filling per profile params */
14651 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
14652 {
14653 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014654 request->match_sets[i].ssid.ssid_len;
14655
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014656 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
14657 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014658 {
14659 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014660 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014661 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014662 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014663 goto error;
14664 }
14665
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014666 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014667 request->match_sets[i].ssid.ssid,
14668 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014669 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14670 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014671 i, pnoRequest.aNetworks[i].ssId.ssId);
14672 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
14673 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
14674 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014675
14676 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014677 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
14678 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014679
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014680 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014681 }
14682
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014683 for (i = 0; i < request->n_ssids; i++)
14684 {
14685 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014686 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014687 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014688 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014689 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014690 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014691 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014692 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014693 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014694 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014695 break;
14696 }
14697 j++;
14698 }
14699 }
14700 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14701 "Number of hidden networks being Configured = %d",
14702 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014703 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080014704 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014705
14706 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14707 if (pnoRequest.p24GProbeTemplate == NULL)
14708 {
14709 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14710 FL("failed to allocate memory p24GProbeTemplate %u"),
14711 SIR_PNO_MAX_PB_REQ_SIZE);
14712 goto error;
14713 }
14714
14715 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14716 if (pnoRequest.p5GProbeTemplate == NULL)
14717 {
14718 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14719 FL("failed to allocate memory p5GProbeTemplate %u"),
14720 SIR_PNO_MAX_PB_REQ_SIZE);
14721 goto error;
14722 }
14723
14724 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14725 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14726
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053014727 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
14728 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014729 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014730 pnoRequest.us24GProbeTemplateLen = request->ie_len;
14731 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
14732 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014733
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014734 pnoRequest.us5GProbeTemplateLen = request->ie_len;
14735 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
14736 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014737 }
14738
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014739 /* Driver gets only one time interval which is hardcoded in
14740 * supplicant for 10000ms. Taking power consumption into account 6 timers
14741 * will be used, Timervalue is increased exponentially i.e 10,20,40,
14742 * 80,160,320 secs. And number of scan cycle for each timer
14743 * is configurable through INI param gPNOScanTimerRepeatValue.
14744 * If it is set to 0 only one timer will be used and PNO scan cycle
14745 * will be repeated after each interval specified by supplicant
14746 * till PNO is disabled.
14747 */
14748 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014749 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014750 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014751 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014752 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
14753
14754 tempInterval = (request->interval)/1000;
14755 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14756 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
14757 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014758 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014759 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014760 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014761 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014762 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014763 tempInterval *= 2;
14764 }
14765 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014766 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014767
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014768 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014769
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014770 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014771 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
14772 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014773 pAdapter->pno_req_status = 0;
14774
Nirav Shah80830bf2013-12-31 16:35:12 +053014775 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14776 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014777 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
14778 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053014779
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014780 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014781 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014782 hdd_cfg80211_sched_scan_done_callback, pAdapter);
14783 if (eHAL_STATUS_SUCCESS != status)
14784 {
14785 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014786 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014787 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014788 goto error;
14789 }
14790
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014791 ret = wait_for_completion_timeout(
14792 &pAdapter->pno_comp_var,
14793 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
14794 if (0 >= ret)
14795 {
14796 // Did not receive the response for PNO enable in time.
14797 // Assuming the PNO enable was success.
14798 // Returning error from here, because we timeout, results
14799 // in side effect of Wifi (Wifi Setting) not to work.
14800 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14801 FL("Timed out waiting for PNO to be Enabled"));
14802 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014803 }
14804
14805 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053014806 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014807
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014808error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014809 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14810 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053014811 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014812 if (pnoRequest.aNetworks)
14813 vos_mem_free(pnoRequest.aNetworks);
14814 if (pnoRequest.p24GProbeTemplate)
14815 vos_mem_free(pnoRequest.p24GProbeTemplate);
14816 if (pnoRequest.p5GProbeTemplate)
14817 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014818
14819 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014820 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014821}
14822
14823/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014824 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
14825 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014826 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014827static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
14828 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14829{
14830 int ret;
14831
14832 vos_ssr_protect(__func__);
14833 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
14834 vos_ssr_unprotect(__func__);
14835
14836 return ret;
14837}
14838
14839/*
14840 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
14841 * Function to disable PNO
14842 */
14843static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014844 struct net_device *dev)
14845{
14846 eHalStatus status = eHAL_STATUS_FAILURE;
14847 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14848 hdd_context_t *pHddCtx;
14849 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014850 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014851 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014852
14853 ENTER();
14854
14855 if (NULL == pAdapter)
14856 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014857 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014858 "%s: HDD adapter is Null", __func__);
14859 return -ENODEV;
14860 }
14861
14862 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014863
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014864 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014865 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014866 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014867 "%s: HDD context is Null", __func__);
14868 return -ENODEV;
14869 }
14870
14871 /* The return 0 is intentional when isLogpInProgress and
14872 * isLoadUnloadInProgress. We did observe a crash due to a return of
14873 * failure in sched_scan_stop , especially for a case where the unload
14874 * of the happens at the same time. The function __cfg80211_stop_sched_scan
14875 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
14876 * success. If it returns a failure , then its next invocation due to the
14877 * clean up of the second interface will have the dev pointer corresponding
14878 * to the first one leading to a crash.
14879 */
14880 if (pHddCtx->isLogpInProgress)
14881 {
14882 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14883 "%s: LOGP in Progress. Ignore!!!", __func__);
14884 return ret;
14885 }
14886
Mihir Shete18156292014-03-11 15:38:30 +053014887 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014888 {
14889 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14890 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14891 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014892 }
14893
14894 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14895 if (NULL == hHal)
14896 {
14897 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14898 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014899 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014900 }
14901
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014902 pnoRequest.enable = 0; /* Disable PNO */
14903 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014904
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014905 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14906 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
14907 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014908 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014909 pAdapter->sessionId,
14910 NULL, pAdapter);
14911 if (eHAL_STATUS_SUCCESS != status)
14912 {
14913 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14914 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014915 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014916 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014917 }
c_hpothu37f21312014-04-09 21:49:54 +053014918 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014919
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014920error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014921 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014922 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014923
14924 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014925 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014926}
14927
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014928/*
14929 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
14930 * NL interface to disable PNO
14931 */
14932static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
14933 struct net_device *dev)
14934{
14935 int ret;
14936
14937 vos_ssr_protect(__func__);
14938 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
14939 vos_ssr_unprotect(__func__);
14940
14941 return ret;
14942}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014943#endif /*FEATURE_WLAN_SCAN_PNO*/
14944
14945
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014946#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014947#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014948static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
14949 struct net_device *dev,
14950 u8 *peer, u8 action_code,
14951 u8 dialog_token,
14952 u16 status_code, u32 peer_capability,
14953 const u8 *buf, size_t len)
14954#else /* TDLS_MGMT_VERSION2 */
14955#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
14956static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
14957 struct net_device *dev,
14958 const u8 *peer, u8 action_code,
14959 u8 dialog_token, u16 status_code,
14960 u32 peer_capability, bool initiator,
14961 const u8 *buf, size_t len)
14962#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
14963static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
14964 struct net_device *dev,
14965 const u8 *peer, u8 action_code,
14966 u8 dialog_token, u16 status_code,
14967 u32 peer_capability, const u8 *buf,
14968 size_t len)
14969#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
14970static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
14971 struct net_device *dev,
14972 u8 *peer, u8 action_code,
14973 u8 dialog_token,
14974 u16 status_code, u32 peer_capability,
14975 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014976#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014977static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
14978 struct net_device *dev,
14979 u8 *peer, u8 action_code,
14980 u8 dialog_token,
14981 u16 status_code, const u8 *buf,
14982 size_t len)
14983#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014984#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014985{
14986
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014987 hdd_adapter_t *pAdapter;
14988 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014989 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070014990 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080014991 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070014992 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053014993 int ret;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053014994#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014995 u32 peer_capability = 0;
14996#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053014997 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014998
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014999 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15000 if (NULL == pAdapter)
15001 {
15002 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15003 "%s: Adapter is NULL",__func__);
15004 return -EINVAL;
15005 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015006 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15007 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
15008 pAdapter->sessionId, action_code));
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015009 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015010 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015011 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015012 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015013 "Invalid arguments");
15014 return -EINVAL;
15015 }
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015016 if (pHddCtx->isLogpInProgress)
15017 {
15018 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15019 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053015020 wlan_hdd_tdls_set_link_status(pAdapter,
15021 peer,
15022 eTDLS_LINK_IDLE,
15023 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015024 return -EBUSY;
15025 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015026 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
15027 {
15028 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15029 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15030 return -EAGAIN;
15031 }
Hoonki Lee27511902013-03-14 18:19:06 -070015032 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015033 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015034 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015035 "%s: TDLS mode is disabled OR not enabled in FW."
15036 MAC_ADDRESS_STR " action %d declined.",
15037 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015038 return -ENOTSUPP;
15039 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015040
Hoonki Lee27511902013-03-14 18:19:06 -070015041 /* other than teardown frame, other mgmt frames are not sent if disabled */
15042 if (SIR_MAC_TDLS_TEARDOWN != action_code)
15043 {
15044 /* if tdls_mode is disabled to respond to peer's request */
15045 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
15046 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015047 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015048 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015049 " TDLS mode is disabled. action %d declined.",
15050 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070015051
15052 return -ENOTSUPP;
15053 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053015054
15055 if (vos_max_concurrent_connections_reached())
15056 {
15057 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15058 return -EINVAL;
15059 }
Hoonki Lee27511902013-03-14 18:19:06 -070015060 }
15061
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015062 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
15063 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053015064 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015065 {
15066 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015067 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015068 " TDLS setup is ongoing. action %d declined.",
15069 __func__, MAC_ADDR_ARRAY(peer), action_code);
15070 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015071 }
15072 }
15073
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015074 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
15075 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080015076 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015077 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15078 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015079 {
15080 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
15081 we return error code at 'add_station()'. Hence we have this
15082 check again in addtion to add_station().
15083 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015084 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015085 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015086 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15087 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015088 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
15089 __func__, MAC_ADDR_ARRAY(peer), action_code,
15090 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053015091 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080015092 }
15093 else
15094 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015095 /* maximum reached. tweak to send error code to peer and return
15096 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015097 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015098 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15099 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015100 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
15101 __func__, MAC_ADDR_ARRAY(peer), status_code,
15102 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070015103 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015104 /* fall through to send setup resp with failure status
15105 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015106 }
15107 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015108 else
15109 {
15110 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053015111 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015112 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015113 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015114 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015115 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
15116 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015117 return -EPERM;
15118 }
15119 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015120 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015121
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015122 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015123 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015124 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
15125 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015126
Hoonki Leea34dd892013-02-05 22:56:02 -080015127 /*Except teardown responder will not be used so just make 0*/
15128 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015129 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080015130 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015131
15132 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015133 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015134
15135 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
15136 responder = pTdlsPeer->is_responder;
15137 else
Hoonki Leea34dd892013-02-05 22:56:02 -080015138 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015139 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015140 "%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 -070015141 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
15142 dialog_token, status_code, len);
15143 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080015144 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015145 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015146
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015147 /* For explicit trigger of DIS_REQ come out of BMPS for
15148 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070015149 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015150 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
15151 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070015152 {
15153 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
15154 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015155 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015156 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015157 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
15158 if (status != VOS_STATUS_SUCCESS) {
15159 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
15160 }
Hoonki Lee14621352013-04-16 17:51:19 -070015161 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015162 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015163 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015164 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
15165 }
15166 }
Hoonki Lee14621352013-04-16 17:51:19 -070015167 }
15168
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015169 /* make sure doesn't call send_mgmt() while it is pending */
15170 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
15171 {
15172 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015173 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015174 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015175 ret = -EBUSY;
15176 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015177 }
15178
15179 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015180 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
15181
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015182 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015183 peer, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015184
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015185 if (VOS_STATUS_SUCCESS != status)
15186 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015187 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15188 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015189 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015190 ret = -EINVAL;
15191 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015192 }
15193
Hoonki Leed37cbb32013-04-20 00:31:14 -070015194 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
15195 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
15196
15197 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015198 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070015199 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015200 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070015201 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015202 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080015203
15204 if (pHddCtx->isLogpInProgress)
15205 {
15206 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15207 "%s: LOGP in Progress. Ignore!!!", __func__);
15208 return -EAGAIN;
15209 }
15210
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015211 ret = -EINVAL;
15212 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015213 }
15214
Gopichand Nakkala05922802013-03-14 12:23:19 -070015215 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070015216 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015217 ret = max_sta_failed;
15218 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070015219 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015220
Hoonki Leea34dd892013-02-05 22:56:02 -080015221 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
15222 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015223 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015224 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15225 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015226 }
15227 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
15228 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015229 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015230 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15231 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015232 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015233
15234 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015235
15236tx_failed:
15237 /* add_station will be called before sending TDLS_SETUP_REQ and
15238 * TDLS_SETUP_RSP and as part of add_station driver will enable
15239 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
15240 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
15241 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
15242 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
15243 */
15244
15245 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
15246 (SIR_MAC_TDLS_SETUP_RSP == action_code))
15247 wlan_hdd_tdls_check_bmps(pAdapter);
15248 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015249}
15250
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015251#if TDLS_MGMT_VERSION2
15252static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15253 u8 *peer, u8 action_code, u8 dialog_token,
15254 u16 status_code, u32 peer_capability,
15255 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015256#else /* TDLS_MGMT_VERSION2 */
15257#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
15258static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15259 struct net_device *dev,
15260 const u8 *peer, u8 action_code,
15261 u8 dialog_token, u16 status_code,
15262 u32 peer_capability, bool initiator,
15263 const u8 *buf, size_t len)
15264#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15265static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15266 struct net_device *dev,
15267 const u8 *peer, u8 action_code,
15268 u8 dialog_token, u16 status_code,
15269 u32 peer_capability, const u8 *buf,
15270 size_t len)
15271#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
15272static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15273 struct net_device *dev,
15274 u8 *peer, u8 action_code,
15275 u8 dialog_token,
15276 u16 status_code, u32 peer_capability,
15277 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015278#else
15279static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15280 u8 *peer, u8 action_code, u8 dialog_token,
15281 u16 status_code, const u8 *buf, size_t len)
15282#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015283#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015284{
15285 int ret;
15286
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015287 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015288#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015289 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15290 dialog_token, status_code,
15291 peer_capability, buf, len);
15292#else /* TDLS_MGMT_VERSION2 */
15293#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
15294 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15295 dialog_token, status_code,
15296 peer_capability, initiator,
15297 buf, len);
15298#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
15299 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15300 dialog_token, status_code,
15301 peer_capability, buf, len);
15302#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
15303 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15304 dialog_token, status_code,
15305 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015306#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015307 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15308 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015309#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015310#endif
15311 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015312
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015313 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015314}
Atul Mittal115287b2014-07-08 13:26:33 +053015315
15316int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015317#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15318 const u8 *peer,
15319#else
Atul Mittal115287b2014-07-08 13:26:33 +053015320 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015321#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015322 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053015323 cfg80211_exttdls_callback callback)
15324{
15325
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015326 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053015327 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015328 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053015329 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15330 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
15331 __func__, MAC_ADDR_ARRAY(peer));
15332
15333 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
15334 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
15335
15336 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015337 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
15338 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
15339 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053015340 return -ENOTSUPP;
15341 }
15342
15343 /* To cater the requirement of establishing the TDLS link
15344 * irrespective of the data traffic , get an entry of TDLS peer.
15345 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015346 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015347 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
15348 if (pTdlsPeer == NULL) {
15349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15350 "%s: peer " MAC_ADDRESS_STR " not existing",
15351 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015352 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015353 return -EINVAL;
15354 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015355 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015356
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053015357 /* check FW TDLS Off Channel capability */
15358 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053015359 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053015360 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015361 {
15362 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
15363 pTdlsPeer->peerParams.global_operating_class =
15364 tdls_peer_params->global_operating_class;
15365 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
15366 pTdlsPeer->peerParams.min_bandwidth_kbps =
15367 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015368 /* check configured channel is valid, non dfs and
15369 * not current operating channel */
15370 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
15371 tdls_peer_params->channel)) &&
15372 (pHddStaCtx) &&
15373 (tdls_peer_params->channel !=
15374 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015375 {
15376 pTdlsPeer->isOffChannelConfigured = TRUE;
15377 }
15378 else
15379 {
15380 pTdlsPeer->isOffChannelConfigured = FALSE;
15381 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15382 "%s: Configured Tdls Off Channel is not valid", __func__);
15383
15384 }
15385 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015386 "%s: tdls_off_channel %d isOffChannelConfigured %d "
15387 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015388 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015389 pTdlsPeer->isOffChannelConfigured,
15390 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015391 }
15392 else
15393 {
15394 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053015395 "%s: TDLS off channel FW capability %d, "
15396 "host capab %d or Invalid TDLS Peer Params", __func__,
15397 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
15398 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015399 }
15400
Atul Mittal115287b2014-07-08 13:26:33 +053015401 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
15402
15403 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15404 " %s TDLS Add Force Peer Failed",
15405 __func__);
15406 return -EINVAL;
15407 }
15408 /*EXT TDLS*/
15409
15410 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
15411 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15412 " %s TDLS set callback Failed",
15413 __func__);
15414 return -EINVAL;
15415 }
15416
15417 return(0);
15418
15419}
15420
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015421int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
15422#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15423 const u8 *peer
15424#else
15425 u8 *peer
15426#endif
15427)
Atul Mittal115287b2014-07-08 13:26:33 +053015428{
15429
15430 hddTdlsPeer_t *pTdlsPeer;
15431 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15432 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15433 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
15434 __func__, MAC_ADDR_ARRAY(peer));
15435
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015436 if (0 != wlan_hdd_validate_context(pHddCtx)) {
15437 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
15438 return -EINVAL;
15439 }
15440
Atul Mittal115287b2014-07-08 13:26:33 +053015441 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
15442 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
15443
15444 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015445 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
15446 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
15447 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053015448 return -ENOTSUPP;
15449 }
15450
15451
15452 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15453
15454 if ( NULL == pTdlsPeer ) {
15455 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015456 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053015457 __func__, MAC_ADDR_ARRAY(peer));
15458 return -EINVAL;
15459 }
15460 else {
15461 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
15462 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015463 /* if channel switch is configured, reset
15464 the channel for this peer */
15465 if (TRUE == pTdlsPeer->isOffChannelConfigured)
15466 {
15467 pTdlsPeer->peerParams.channel = 0;
15468 pTdlsPeer->isOffChannelConfigured = FALSE;
15469 }
Atul Mittal115287b2014-07-08 13:26:33 +053015470 }
15471
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015472 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
15473 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053015474 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015475 }
Atul Mittal115287b2014-07-08 13:26:33 +053015476
15477 /*EXT TDLS*/
15478
15479 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
15480
15481 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15482 " %s TDLS set callback Failed",
15483 __func__);
15484 return -EINVAL;
15485 }
15486 return(0);
15487
15488}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015489static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015490#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15491 const u8 *peer,
15492#else
15493 u8 *peer,
15494#endif
15495 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015496{
15497 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15498 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015499 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015500 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015501
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015502 ENTER();
15503
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015504 if (!pAdapter) {
15505 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
15506 return -EINVAL;
15507 }
15508
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015509 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15510 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
15511 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015512 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015513 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015514 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070015515 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015516 return -EINVAL;
15517 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015518
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015519 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015520 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015521 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015522 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015523 }
15524
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015525
15526 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015527 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015528 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015530 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
15531 "Cannot process TDLS commands",
15532 pHddCtx->cfg_ini->fEnableTDLSSupport,
15533 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015534 return -ENOTSUPP;
15535 }
15536
15537 switch (oper) {
15538 case NL80211_TDLS_ENABLE_LINK:
15539 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015540 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015541 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015542 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053015543 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015544 tANI_U16 numCurrTdlsPeers = 0;
15545 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015546 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015547
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015548 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15549 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
15550 __func__, MAC_ADDR_ARRAY(peer));
Sunil Dutt41de4e22013-11-14 18:09:02 +053015551 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053015552 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053015553 if ( NULL == pTdlsPeer ) {
15554 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15555 " (oper %d) not exsting. ignored",
15556 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15557 return -EINVAL;
15558 }
15559
15560 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15561 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15562 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15563 "NL80211_TDLS_ENABLE_LINK");
15564
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070015565 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
15566 {
15567 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
15568 MAC_ADDRESS_STR " failed",
15569 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
15570 return -EINVAL;
15571 }
15572
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053015573 /* before starting tdls connection, set tdls
15574 * off channel established status to default value */
15575 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015576 /* TDLS Off Channel, Disable tdls channel switch,
15577 when there are more than one tdls link */
15578 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053015579 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015580 {
15581 /* get connected peer and send disable tdls off chan */
15582 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015583 if ((connPeer) &&
15584 (connPeer->isOffChannelSupported == TRUE) &&
15585 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015586 {
15587 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15588 "%s: More then one peer connected, Disable "
15589 "TDLS channel switch", __func__);
15590
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015591 connPeer->isOffChannelEstablished = FALSE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015592 ret = sme_SendTdlsChanSwitchReq(
15593 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015594 pAdapter->sessionId,
15595 connPeer->peerMac,
15596 connPeer->peerParams.channel,
15597 TDLS_OFF_CHANNEL_BW_OFFSET,
15598 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015599 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015600 hddLog(VOS_TRACE_LEVEL_ERROR,
15601 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015602 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015603 }
15604 else
15605 {
15606 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15607 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015608 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015609 "isOffChannelConfigured %d",
15610 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015611 (connPeer ? (connPeer->isOffChannelSupported)
15612 : -1),
15613 (connPeer ? (connPeer->isOffChannelConfigured)
15614 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015615 }
15616 }
15617
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015618 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015619 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015620 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053015621
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015622 if (0 != wlan_hdd_tdls_get_link_establish_params(
15623 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015624 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015625 return -EINVAL;
15626 }
15627 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015628
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015629 ret = sme_SendTdlsLinkEstablishParams(
15630 WLAN_HDD_GET_HAL_CTX(pAdapter),
15631 pAdapter->sessionId, peer,
15632 &tdlsLinkEstablishParams);
15633 if (ret != VOS_STATUS_SUCCESS) {
15634 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
15635 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015636 /* Send TDLS peer UAPSD capabilities to the firmware and
15637 * register with the TL on after the response for this operation
15638 * is received .
15639 */
15640 ret = wait_for_completion_interruptible_timeout(
15641 &pAdapter->tdls_link_establish_req_comp,
15642 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
15643 if (ret <= 0)
15644 {
15645 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015646 FL("Link Establish Request Failed Status %ld"),
15647 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015648 return -EINVAL;
15649 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015650 }
Atul Mittal115287b2014-07-08 13:26:33 +053015651 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15652 eTDLS_LINK_CONNECTED,
15653 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053015654 staDesc.ucSTAId = pTdlsPeer->staId;
15655 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015656 ret = WLANTL_UpdateTdlsSTAClient(
15657 pHddCtx->pvosContext,
15658 &staDesc);
15659 if (ret != VOS_STATUS_SUCCESS) {
15660 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
15661 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053015662
Gopichand Nakkala471708b2013-06-04 20:03:01 +053015663 /* Mark TDLS client Authenticated .*/
15664 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
15665 pTdlsPeer->staId,
15666 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015667 if (VOS_STATUS_SUCCESS == status)
15668 {
Hoonki Lee14621352013-04-16 17:51:19 -070015669 if (pTdlsPeer->is_responder == 0)
15670 {
15671 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
15672
15673 wlan_hdd_tdls_timer_restart(pAdapter,
15674 &pTdlsPeer->initiatorWaitTimeoutTimer,
15675 WAIT_TIME_TDLS_INITIATOR);
15676 /* suspend initiator TX until it receives direct packet from the
15677 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015678 ret = WLANTL_SuspendDataTx(
15679 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15680 &staId, NULL);
15681 if (ret != VOS_STATUS_SUCCESS) {
15682 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
15683 }
Hoonki Lee14621352013-04-16 17:51:19 -070015684 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015685
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015686 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015687 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015688 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015689 suppChannelLen =
15690 tdlsLinkEstablishParams.supportedChannelsLen;
15691
15692 if ((suppChannelLen > 0) &&
15693 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
15694 {
15695 tANI_U8 suppPeerChannel = 0;
15696 int i = 0;
15697 for (i = 0U; i < suppChannelLen; i++)
15698 {
15699 suppPeerChannel =
15700 tdlsLinkEstablishParams.supportedChannels[i];
15701
15702 pTdlsPeer->isOffChannelSupported = FALSE;
15703 if (suppPeerChannel ==
15704 pTdlsPeer->peerParams.channel)
15705 {
15706 pTdlsPeer->isOffChannelSupported = TRUE;
15707 break;
15708 }
15709 }
15710 }
15711 else
15712 {
15713 pTdlsPeer->isOffChannelSupported = FALSE;
15714 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015715 }
15716 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15717 "%s: TDLS channel switch request for channel "
15718 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015719 "%d isOffChannelSupported %d", __func__,
15720 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015721 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015722 suppChannelLen,
15723 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015724
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015725 /* TDLS Off Channel, Enable tdls channel switch,
15726 when their is only one tdls link and it supports */
15727 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15728 if ((numCurrTdlsPeers == 1) &&
15729 (TRUE == pTdlsPeer->isOffChannelSupported) &&
15730 (TRUE == pTdlsPeer->isOffChannelConfigured))
15731 {
15732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15733 "%s: Send TDLS channel switch request for channel %d",
15734 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015735
15736 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015737 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
15738 pAdapter->sessionId,
15739 pTdlsPeer->peerMac,
15740 pTdlsPeer->peerParams.channel,
15741 TDLS_OFF_CHANNEL_BW_OFFSET,
15742 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015743 if (ret != VOS_STATUS_SUCCESS) {
15744 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
15745 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015746 }
15747 else
15748 {
15749 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15750 "%s: TDLS channel switch request not sent"
15751 " numCurrTdlsPeers %d "
15752 "isOffChannelSupported %d "
15753 "isOffChannelConfigured %d",
15754 __func__, numCurrTdlsPeers,
15755 pTdlsPeer->isOffChannelSupported,
15756 pTdlsPeer->isOffChannelConfigured);
15757 }
15758
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015759 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015760 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015761
15762 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015763 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
15764 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015765 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015766 int ac;
15767 uint8 ucAc[4] = { WLANTL_AC_VO,
15768 WLANTL_AC_VI,
15769 WLANTL_AC_BK,
15770 WLANTL_AC_BE };
15771 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
15772 for(ac=0; ac < 4; ac++)
15773 {
15774 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15775 pTdlsPeer->staId, ucAc[ac],
15776 tlTid[ac], tlTid[ac], 0, 0,
15777 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015778 if (status != VOS_STATUS_SUCCESS) {
15779 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
15780 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015781 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015782 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015783 }
15784
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015785 }
15786 break;
15787 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080015788 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015789 tANI_U16 numCurrTdlsPeers = 0;
15790 hddTdlsPeer_t *connPeer = NULL;
15791
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015792 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15793 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
15794 __func__, MAC_ADDR_ARRAY(peer));
15795
Sunil Dutt41de4e22013-11-14 18:09:02 +053015796 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15797
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015798
Sunil Dutt41de4e22013-11-14 18:09:02 +053015799 if ( NULL == pTdlsPeer ) {
15800 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15801 " (oper %d) not exsting. ignored",
15802 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15803 return -EINVAL;
15804 }
15805
15806 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15807 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15808 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15809 "NL80211_TDLS_DISABLE_LINK");
15810
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015811 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080015812 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015813 long status;
15814
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053015815 /* set tdls off channel status to false for this peer */
15816 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053015817 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15818 eTDLS_LINK_TEARING,
15819 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
15820 eTDLS_LINK_UNSPECIFIED:
15821 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015822 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
15823
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015824 status = sme_DeleteTdlsPeerSta(
15825 WLAN_HDD_GET_HAL_CTX(pAdapter),
15826 pAdapter->sessionId, peer );
15827 if (status != VOS_STATUS_SUCCESS) {
15828 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
15829 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015830
15831 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
15832 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053015833 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053015834 eTDLS_LINK_IDLE,
15835 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015836 if (status <= 0)
15837 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015838 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15839 "%s: Del station failed status %ld",
15840 __func__, status);
15841 return -EPERM;
15842 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015843
15844 /* TDLS Off Channel, Enable tdls channel switch,
15845 when their is only one tdls link and it supports */
15846 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15847 if (numCurrTdlsPeers == 1)
15848 {
15849 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
15850 if ((connPeer) &&
15851 (connPeer->isOffChannelSupported == TRUE) &&
15852 (connPeer->isOffChannelConfigured == TRUE))
15853 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015854 connPeer->isOffChannelEstablished = TRUE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015855 status = sme_SendTdlsChanSwitchReq(
15856 WLAN_HDD_GET_HAL_CTX(pAdapter),
15857 pAdapter->sessionId,
15858 connPeer->peerMac,
15859 connPeer->peerParams.channel,
15860 TDLS_OFF_CHANNEL_BW_OFFSET,
15861 TDLS_CHANNEL_SWITCH_ENABLE);
15862 if (status != VOS_STATUS_SUCCESS) {
15863 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
15864 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015865 }
15866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15867 "%s: TDLS channel switch "
15868 "isOffChannelSupported %d "
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015869 "isOffChannelConfigured %d "
15870 "isOffChannelEstablished %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015871 __func__,
15872 (connPeer ? connPeer->isOffChannelSupported : -1),
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015873 (connPeer ? connPeer->isOffChannelConfigured : -1),
15874 (connPeer ? connPeer->isOffChannelEstablished : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015875 }
15876 else
15877 {
15878 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15879 "%s: TDLS channel switch request not sent "
15880 "numCurrTdlsPeers %d ",
15881 __func__, numCurrTdlsPeers);
15882 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015883 }
15884 else
15885 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015886 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15887 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080015888 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015889 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015890 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015891 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015892 {
Atul Mittal115287b2014-07-08 13:26:33 +053015893 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015894
Atul Mittal115287b2014-07-08 13:26:33 +053015895 if (0 != status)
15896 {
15897 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015898 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053015899 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015900 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053015901 break;
15902 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015903 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015904 {
Atul Mittal115287b2014-07-08 13:26:33 +053015905 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
15906 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015907 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053015908 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015909
Atul Mittal115287b2014-07-08 13:26:33 +053015910 if (0 != status)
15911 {
15912 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015913 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053015914 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053015915 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053015916 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015917 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015918 case NL80211_TDLS_DISCOVERY_REQ:
15919 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015920 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015921 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015922 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015923 return -ENOTSUPP;
15924 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015925 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15926 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015927 return -ENOTSUPP;
15928 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015929
15930 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015931 return 0;
15932}
Chilam NG571c65a2013-01-19 12:27:36 +053015933
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015934static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015935#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15936 const u8 *peer,
15937#else
15938 u8 *peer,
15939#endif
15940 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015941{
15942 int ret;
15943
15944 vos_ssr_protect(__func__);
15945 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
15946 vos_ssr_unprotect(__func__);
15947
15948 return ret;
15949}
15950
Chilam NG571c65a2013-01-19 12:27:36 +053015951int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
15952 struct net_device *dev, u8 *peer)
15953{
Arif Hussaina7c8e412013-11-20 11:06:42 -080015954 hddLog(VOS_TRACE_LEVEL_INFO,
15955 "tdls send discover req: "MAC_ADDRESS_STR,
15956 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053015957
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015958#if TDLS_MGMT_VERSION2
15959 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15960 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
15961#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015962#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
15963 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15964 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
15965#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15966 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15967 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
15968#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
15969 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15970 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
15971#else
Chilam NG571c65a2013-01-19 12:27:36 +053015972 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15973 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015974#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015975#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053015976}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015977#endif
15978
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015979#ifdef WLAN_FEATURE_GTK_OFFLOAD
15980/*
15981 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
15982 * Callback rountine called upon receiving response for
15983 * get offload info
15984 */
15985void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
15986 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
15987{
15988
15989 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053015990 tANI_U8 tempReplayCounter[8];
15991 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015992
15993 ENTER();
15994
15995 if (NULL == pAdapter)
15996 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053015997 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053015998 "%s: HDD adapter is Null", __func__);
15999 return ;
16000 }
16001
16002 if (NULL == pGtkOffloadGetInfoRsp)
16003 {
16004 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16005 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
16006 return ;
16007 }
16008
16009 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
16010 {
16011 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16012 "%s: wlan Failed to get replay counter value",
16013 __func__);
16014 return ;
16015 }
16016
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016017 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16018 /* Update replay counter */
16019 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
16020 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16021
16022 {
16023 /* changing from little to big endian since supplicant
16024 * works on big endian format
16025 */
16026 int i;
16027 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16028
16029 for (i = 0; i < 8; i++)
16030 {
16031 tempReplayCounter[7-i] = (tANI_U8)p[i];
16032 }
16033 }
16034
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016035 /* Update replay counter to NL */
16036 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016037 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016038}
16039
16040/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016041 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016042 * This function is used to offload GTK rekeying job to the firmware.
16043 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016044int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016045 struct cfg80211_gtk_rekey_data *data)
16046{
16047 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16048 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16049 hdd_station_ctx_t *pHddStaCtx;
16050 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016051 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016052 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016053 eHalStatus status = eHAL_STATUS_FAILURE;
16054
16055 ENTER();
16056
16057 if (NULL == pAdapter)
16058 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016059 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016060 "%s: HDD adapter is Null", __func__);
16061 return -ENODEV;
16062 }
16063
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016064 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16065 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
16066 pAdapter->sessionId, pAdapter->device_mode));
16067
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016068 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016069 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016070 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016071 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016072 }
16073
16074 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16075 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16076 if (NULL == hHal)
16077 {
16078 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16079 "%s: HAL context is Null!!!", __func__);
16080 return -EAGAIN;
16081 }
16082
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016083 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
16084 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
16085 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
16086 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016087 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016088 {
16089 /* changing from big to little endian since driver
16090 * works on little endian format
16091 */
16092 tANI_U8 *p =
16093 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
16094 int i;
16095
16096 for (i = 0; i < 8; i++)
16097 {
16098 p[7-i] = data->replay_ctr[i];
16099 }
16100 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016101
16102 if (TRUE == pHddCtx->hdd_wlan_suspended)
16103 {
16104 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016105 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
16106 sizeof (tSirGtkOffloadParams));
16107 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016108 pAdapter->sessionId);
16109
16110 if (eHAL_STATUS_SUCCESS != status)
16111 {
16112 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16113 "%s: sme_SetGTKOffload failed, returned %d",
16114 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016115
16116 /* Need to clear any trace of key value in the memory.
16117 * Thus zero out the memory even though it is local
16118 * variable.
16119 */
16120 vos_mem_zero(&hddGtkOffloadReqParams,
16121 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016122 return status;
16123 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016124 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16125 "%s: sme_SetGTKOffload successfull", __func__);
16126 }
16127 else
16128 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016129 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16130 "%s: wlan not suspended GTKOffload request is stored",
16131 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016132 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016133
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016134 /* Need to clear any trace of key value in the memory.
16135 * Thus zero out the memory even though it is local
16136 * variable.
16137 */
16138 vos_mem_zero(&hddGtkOffloadReqParams,
16139 sizeof(hddGtkOffloadReqParams));
16140
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016141 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016142 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016143}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016144
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016145int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
16146 struct cfg80211_gtk_rekey_data *data)
16147{
16148 int ret;
16149
16150 vos_ssr_protect(__func__);
16151 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
16152 vos_ssr_unprotect(__func__);
16153
16154 return ret;
16155}
16156#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016157/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016158 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016159 * This function is used to set access control policy
16160 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016161static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
16162 struct net_device *dev,
16163 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016164{
16165 int i;
16166 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16167 hdd_hostapd_state_t *pHostapdState;
16168 tsap_Config_t *pConfig;
16169 v_CONTEXT_t pVosContext = NULL;
16170 hdd_context_t *pHddCtx;
16171 int status;
16172
16173 ENTER();
16174
16175 if (NULL == pAdapter)
16176 {
16177 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16178 "%s: HDD adapter is Null", __func__);
16179 return -ENODEV;
16180 }
16181
16182 if (NULL == params)
16183 {
16184 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16185 "%s: params is Null", __func__);
16186 return -EINVAL;
16187 }
16188
16189 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16190 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016191 if (0 != status)
16192 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016193 return status;
16194 }
16195
16196 pVosContext = pHddCtx->pvosContext;
16197 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
16198
16199 if (NULL == pHostapdState)
16200 {
16201 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16202 "%s: pHostapdState is Null", __func__);
16203 return -EINVAL;
16204 }
16205
16206 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
16207 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016208 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16209 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
16210 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016211
16212 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
16213 {
16214 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
16215
16216 /* default value */
16217 pConfig->num_accept_mac = 0;
16218 pConfig->num_deny_mac = 0;
16219
16220 /**
16221 * access control policy
16222 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
16223 * listed in hostapd.deny file.
16224 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
16225 * listed in hostapd.accept file.
16226 */
16227 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
16228 {
16229 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
16230 }
16231 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
16232 {
16233 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
16234 }
16235 else
16236 {
16237 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16238 "%s:Acl Policy : %d is not supported",
16239 __func__, params->acl_policy);
16240 return -ENOTSUPP;
16241 }
16242
16243 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
16244 {
16245 pConfig->num_accept_mac = params->n_acl_entries;
16246 for (i = 0; i < params->n_acl_entries; i++)
16247 {
16248 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16249 "** Add ACL MAC entry %i in WhiletList :"
16250 MAC_ADDRESS_STR, i,
16251 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
16252
16253 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
16254 sizeof(qcmacaddr));
16255 }
16256 }
16257 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
16258 {
16259 pConfig->num_deny_mac = params->n_acl_entries;
16260 for (i = 0; i < params->n_acl_entries; i++)
16261 {
16262 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16263 "** Add ACL MAC entry %i in BlackList :"
16264 MAC_ADDRESS_STR, i,
16265 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
16266
16267 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
16268 sizeof(qcmacaddr));
16269 }
16270 }
16271
16272 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
16273 {
16274 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16275 "%s: SAP Set Mac Acl fail", __func__);
16276 return -EINVAL;
16277 }
16278 }
16279 else
16280 {
16281 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016282 "%s: Invalid device_mode = %s (%d)",
16283 __func__, hdd_device_modetoString(pAdapter->device_mode),
16284 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016285 return -EINVAL;
16286 }
16287
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016288 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016289 return 0;
16290}
16291
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016292static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
16293 struct net_device *dev,
16294 const struct cfg80211_acl_data *params)
16295{
16296 int ret;
16297 vos_ssr_protect(__func__);
16298 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
16299 vos_ssr_unprotect(__func__);
16300
16301 return ret;
16302}
16303
Leo Chang9056f462013-08-01 19:21:11 -070016304#ifdef WLAN_NL80211_TESTMODE
16305#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070016306void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070016307(
16308 void *pAdapter,
16309 void *indCont
16310)
16311{
Leo Changd9df8aa2013-09-26 13:32:26 -070016312 tSirLPHBInd *lphbInd;
16313 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053016314 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070016315
16316 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016317 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070016318
c_hpothu73f35e62014-04-18 13:40:08 +053016319 if (pAdapter == NULL)
16320 {
16321 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16322 "%s: pAdapter is NULL\n",__func__);
16323 return;
16324 }
16325
Leo Chang9056f462013-08-01 19:21:11 -070016326 if (NULL == indCont)
16327 {
16328 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016329 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070016330 return;
16331 }
16332
c_hpothu73f35e62014-04-18 13:40:08 +053016333 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070016334 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070016335 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053016336 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070016337 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070016338 GFP_ATOMIC);
16339 if (!skb)
16340 {
16341 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16342 "LPHB timeout, NL buffer alloc fail");
16343 return;
16344 }
16345
Leo Changac3ba772013-10-07 09:47:04 -070016346 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070016347 {
16348 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16349 "WLAN_HDD_TM_ATTR_CMD put fail");
16350 goto nla_put_failure;
16351 }
Leo Changac3ba772013-10-07 09:47:04 -070016352 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070016353 {
16354 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16355 "WLAN_HDD_TM_ATTR_TYPE put fail");
16356 goto nla_put_failure;
16357 }
Leo Changac3ba772013-10-07 09:47:04 -070016358 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070016359 sizeof(tSirLPHBInd), lphbInd))
16360 {
16361 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16362 "WLAN_HDD_TM_ATTR_DATA put fail");
16363 goto nla_put_failure;
16364 }
Leo Chang9056f462013-08-01 19:21:11 -070016365 cfg80211_testmode_event(skb, GFP_ATOMIC);
16366 return;
16367
16368nla_put_failure:
16369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16370 "NLA Put fail");
16371 kfree_skb(skb);
16372
16373 return;
16374}
16375#endif /* FEATURE_WLAN_LPHB */
16376
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016377static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070016378{
16379 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
16380 int err = 0;
16381#ifdef FEATURE_WLAN_LPHB
16382 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070016383 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016384
16385 ENTER();
16386
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016387 err = wlan_hdd_validate_context(pHddCtx);
16388 if (0 != err)
16389 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016390 return err;
16391 }
Leo Chang9056f462013-08-01 19:21:11 -070016392#endif /* FEATURE_WLAN_LPHB */
16393
16394 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
16395 if (err)
16396 {
16397 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16398 "%s Testmode INV ATTR", __func__);
16399 return err;
16400 }
16401
16402 if (!tb[WLAN_HDD_TM_ATTR_CMD])
16403 {
16404 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16405 "%s Testmode INV CMD", __func__);
16406 return -EINVAL;
16407 }
16408
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016409 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16410 TRACE_CODE_HDD_CFG80211_TESTMODE,
16411 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070016412 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
16413 {
16414#ifdef FEATURE_WLAN_LPHB
16415 /* Low Power Heartbeat configuration request */
16416 case WLAN_HDD_TM_CMD_WLAN_HB:
16417 {
16418 int buf_len;
16419 void *buf;
16420 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080016421 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070016422
16423 if (!tb[WLAN_HDD_TM_ATTR_DATA])
16424 {
16425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16426 "%s Testmode INV DATA", __func__);
16427 return -EINVAL;
16428 }
16429
16430 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
16431 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080016432
16433 hb_params_temp =(tSirLPHBReq *)buf;
16434 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
16435 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
16436 return -EINVAL;
16437
Leo Chang9056f462013-08-01 19:21:11 -070016438 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
16439 if (NULL == hb_params)
16440 {
16441 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16442 "%s Request Buffer Alloc Fail", __func__);
16443 return -EINVAL;
16444 }
16445
16446 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070016447 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
16448 hb_params,
16449 wlan_hdd_cfg80211_lphb_ind_handler);
16450 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070016451 {
Leo Changd9df8aa2013-09-26 13:32:26 -070016452 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16453 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070016454 vos_mem_free(hb_params);
16455 }
Leo Chang9056f462013-08-01 19:21:11 -070016456 return 0;
16457 }
16458#endif /* FEATURE_WLAN_LPHB */
16459 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016460 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16461 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070016462 return -EOPNOTSUPP;
16463 }
16464
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016465 EXIT();
16466 return err;
Leo Chang9056f462013-08-01 19:21:11 -070016467}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016468
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053016469static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
16470#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
16471 struct wireless_dev *wdev,
16472#endif
16473 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016474{
16475 int ret;
16476
16477 vos_ssr_protect(__func__);
16478 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
16479 vos_ssr_unprotect(__func__);
16480
16481 return ret;
16482}
Leo Chang9056f462013-08-01 19:21:11 -070016483#endif /* CONFIG_NL80211_TESTMODE */
16484
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016485static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016486 struct net_device *dev,
16487 int idx, struct survey_info *survey)
16488{
16489 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16490 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053016491 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016492 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053016493 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016494 v_S7_t snr,rssi;
16495 int status, i, j, filled = 0;
16496
16497 ENTER();
16498
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016499 if (NULL == pAdapter)
16500 {
16501 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16502 "%s: HDD adapter is Null", __func__);
16503 return -ENODEV;
16504 }
16505
16506 if (NULL == wiphy)
16507 {
16508 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16509 "%s: wiphy is Null", __func__);
16510 return -ENODEV;
16511 }
16512
16513 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16514 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016515 if (0 != status)
16516 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016517 return status;
16518 }
16519
Mihir Sheted9072e02013-08-21 17:02:29 +053016520 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16521
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016522 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053016523 0 != pAdapter->survey_idx ||
16524 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016525 {
16526 /* The survey dump ops when implemented completely is expected to
16527 * return a survey of all channels and the ops is called by the
16528 * kernel with incremental values of the argument 'idx' till it
16529 * returns -ENONET. But we can only support the survey for the
16530 * operating channel for now. survey_idx is used to track
16531 * that the ops is called only once and then return -ENONET for
16532 * the next iteration
16533 */
16534 pAdapter->survey_idx = 0;
16535 return -ENONET;
16536 }
16537
Mukul Sharma9d5233b2015-06-11 20:28:20 +053016538 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
16539 {
16540 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16541 "%s: Roaming in progress, hence return ", __func__);
16542 return -ENONET;
16543 }
16544
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016545 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16546
16547 wlan_hdd_get_snr(pAdapter, &snr);
16548 wlan_hdd_get_rssi(pAdapter, &rssi);
16549
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016550 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16551 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
16552 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016553 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
16554 hdd_wlan_get_freq(channel, &freq);
16555
16556
16557 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
16558 {
16559 if (NULL == wiphy->bands[i])
16560 {
16561 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
16562 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
16563 continue;
16564 }
16565
16566 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
16567 {
16568 struct ieee80211_supported_band *band = wiphy->bands[i];
16569
16570 if (band->channels[j].center_freq == (v_U16_t)freq)
16571 {
16572 survey->channel = &band->channels[j];
16573 /* The Rx BDs contain SNR values in dB for the received frames
16574 * while the supplicant expects noise. So we calculate and
16575 * return the value of noise (dBm)
16576 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
16577 */
16578 survey->noise = rssi - snr;
16579 survey->filled = SURVEY_INFO_NOISE_DBM;
16580 filled = 1;
16581 }
16582 }
16583 }
16584
16585 if (filled)
16586 pAdapter->survey_idx = 1;
16587 else
16588 {
16589 pAdapter->survey_idx = 0;
16590 return -ENONET;
16591 }
16592
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016593 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016594 return 0;
16595}
16596
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016597static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
16598 struct net_device *dev,
16599 int idx, struct survey_info *survey)
16600{
16601 int ret;
16602
16603 vos_ssr_protect(__func__);
16604 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
16605 vos_ssr_unprotect(__func__);
16606
16607 return ret;
16608}
16609
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016610/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016611 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016612 * this is called when cfg80211 driver resume
16613 * driver updates latest sched_scan scan result(if any) to cfg80211 database
16614 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016615int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016616{
16617 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16618 hdd_adapter_t *pAdapter;
16619 hdd_adapter_list_node_t *pAdapterNode, *pNext;
16620 VOS_STATUS status = VOS_STATUS_SUCCESS;
16621
16622 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016623
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016624 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016625 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016626 return 0;
16627 }
16628
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016629 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
16630 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016631 spin_lock(&pHddCtx->schedScan_lock);
16632 pHddCtx->isWiphySuspended = FALSE;
16633 if (TRUE != pHddCtx->isSchedScanUpdatePending)
16634 {
16635 spin_unlock(&pHddCtx->schedScan_lock);
16636 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16637 "%s: Return resume is not due to PNO indication", __func__);
16638 return 0;
16639 }
16640 // Reset flag to avoid updatating cfg80211 data old results again
16641 pHddCtx->isSchedScanUpdatePending = FALSE;
16642 spin_unlock(&pHddCtx->schedScan_lock);
16643
16644 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
16645
16646 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
16647 {
16648 pAdapter = pAdapterNode->pAdapter;
16649 if ( (NULL != pAdapter) &&
16650 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
16651 {
16652 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016653 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016654 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
16655 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016656 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016657 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016658 {
16659 /* Acquire wakelock to handle the case where APP's tries to
16660 * suspend immediately after updating the scan results. Whis
16661 * results in app's is in suspended state and not able to
16662 * process the connect request to AP
16663 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053016664 hdd_prevent_suspend_timeout(2000,
16665 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016666 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016667 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016668
16669 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16670 "%s : cfg80211 scan result database updated", __func__);
16671
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016672 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016673 return 0;
16674
16675 }
16676 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16677 pAdapterNode = pNext;
16678 }
16679
16680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16681 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016682 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016683 return 0;
16684}
16685
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016686int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
16687{
16688 int ret;
16689
16690 vos_ssr_protect(__func__);
16691 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
16692 vos_ssr_unprotect(__func__);
16693
16694 return ret;
16695}
16696
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016697/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016698 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016699 * this is called when cfg80211 driver suspends
16700 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016701int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016702 struct cfg80211_wowlan *wow)
16703{
16704 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016705 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016706
16707 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016708
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016709 ret = wlan_hdd_validate_context(pHddCtx);
16710 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016711 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016712 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016713 }
16714
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016715
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016716 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16717 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
16718 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016719 pHddCtx->isWiphySuspended = TRUE;
16720
16721 EXIT();
16722
16723 return 0;
16724}
16725
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016726int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
16727 struct cfg80211_wowlan *wow)
16728{
16729 int ret;
16730
16731 vos_ssr_protect(__func__);
16732 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
16733 vos_ssr_unprotect(__func__);
16734
16735 return ret;
16736}
Jeff Johnson295189b2012-06-20 16:38:30 -070016737/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016738static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070016739{
16740 .add_virtual_intf = wlan_hdd_add_virtual_intf,
16741 .del_virtual_intf = wlan_hdd_del_virtual_intf,
16742 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
16743 .change_station = wlan_hdd_change_station,
16744#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
16745 .add_beacon = wlan_hdd_cfg80211_add_beacon,
16746 .del_beacon = wlan_hdd_cfg80211_del_beacon,
16747 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016748#else
16749 .start_ap = wlan_hdd_cfg80211_start_ap,
16750 .change_beacon = wlan_hdd_cfg80211_change_beacon,
16751 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070016752#endif
16753 .change_bss = wlan_hdd_cfg80211_change_bss,
16754 .add_key = wlan_hdd_cfg80211_add_key,
16755 .get_key = wlan_hdd_cfg80211_get_key,
16756 .del_key = wlan_hdd_cfg80211_del_key,
16757 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080016758#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070016759 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080016760#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016761 .scan = wlan_hdd_cfg80211_scan,
16762 .connect = wlan_hdd_cfg80211_connect,
16763 .disconnect = wlan_hdd_cfg80211_disconnect,
16764 .join_ibss = wlan_hdd_cfg80211_join_ibss,
16765 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
16766 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
16767 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
16768 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070016769 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
16770 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053016771 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070016772#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16773 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
16774 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
16775 .set_txq_params = wlan_hdd_set_txq_params,
16776#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016777 .get_station = wlan_hdd_cfg80211_get_station,
16778 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
16779 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016780 .add_station = wlan_hdd_cfg80211_add_station,
16781#ifdef FEATURE_WLAN_LFR
16782 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
16783 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
16784 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
16785#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016786#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
16787 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
16788#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016789#ifdef FEATURE_WLAN_TDLS
16790 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
16791 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
16792#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016793#ifdef WLAN_FEATURE_GTK_OFFLOAD
16794 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
16795#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016796#ifdef FEATURE_WLAN_SCAN_PNO
16797 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
16798 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
16799#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016800 .resume = wlan_hdd_cfg80211_resume_wlan,
16801 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016802 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070016803#ifdef WLAN_NL80211_TESTMODE
16804 .testmode_cmd = wlan_hdd_cfg80211_testmode,
16805#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016806 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070016807};
16808