blob: b6844321a4e05f79b8d7e0a77a949d3478c6a07b [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05302 * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
Kiet Lam842dad02014-02-18 18:44:02 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
Kiet Lama7f454d2014-07-24 12:04:06 -070023 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +053026 *
Kiet Lamaa8e15a2014-02-11 23:30:06 -080027 */
Kiet Lam842dad02014-02-18 18:44:02 -080028
29
Kiet Lama7f454d2014-07-24 12:04:06 -070030
31
Jeff Johnson295189b2012-06-20 16:38:30 -070032/**========================================================================
33
34 \file wlan_hdd_cfg80211.c
35
36 \brief WLAN Host Device Driver implementation
37
Jeff Johnson295189b2012-06-20 16:38:30 -070038 ========================================================================*/
39
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070040/**=========================================================================
Jeff Johnson295189b2012-06-20 16:38:30 -070041
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070042 EDIT HISTORY FOR FILE
Jeff Johnson295189b2012-06-20 16:38:30 -070043
44
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070045 This section contains comments describing changes made to the module.
46 Notice that changes are listed in reverse chronological order.
Jeff Johnson295189b2012-06-20 16:38:30 -070047
48
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070049 $Header:$ $DateTime: $ $Author: $
Jeff Johnson295189b2012-06-20 16:38:30 -070050
51
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070052 when who what, where, why
Jeff Johnson295189b2012-06-20 16:38:30 -070053 -------- --- --------------------------------------------------------
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070054 21/12/09 Ashwani Created module.
Jeff Johnson295189b2012-06-20 16:38:30 -070055
56 07/06/10 Kumar Deepak Implemented cfg80211 callbacks for ANDROID
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -070057 Ganesh K
Jeff Johnson295189b2012-06-20 16:38:30 -070058 ==========================================================================*/
59
Jeff Johnson295189b2012-06-20 16:38:30 -070060
61#include <linux/version.h>
62#include <linux/module.h>
63#include <linux/kernel.h>
64#include <linux/init.h>
65#include <linux/wireless.h>
66#include <wlan_hdd_includes.h>
67#include <net/arp.h>
68#include <net/cfg80211.h>
69#include <linux/wireless.h>
70#include <wlan_hdd_wowl.h>
71#include <aniGlobal.h>
72#include "ccmApi.h"
73#include "sirParams.h"
74#include "dot11f.h"
75#include "wlan_hdd_assoc.h"
76#include "wlan_hdd_wext.h"
77#include "sme_Api.h"
78#include "wlan_hdd_p2p.h"
79#include "wlan_hdd_cfg80211.h"
80#include "wlan_hdd_hostapd.h"
81#include "sapInternal.h"
82#include "wlan_hdd_softap_tx_rx.h"
83#include "wlan_hdd_main.h"
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053084#include "wlan_hdd_assoc.h"
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053085#include "wlan_hdd_power.h"
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053086#include "wlan_hdd_trace.h"
87#include "vos_types.h"
88#include "vos_trace.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070089#ifdef WLAN_BTAMP_FEATURE
90#include "bap_hdd_misc.h"
91#endif
92#include <qc_sap_ioctl.h>
Mohit Khanna698ba2a2012-12-04 15:08:18 -080093#include "wlan_hdd_tdls.h"
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053094#include "wlan_hdd_wmm.h"
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053095#include "wlan_qct_wda.h"
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +053096#include "wlan_nv.h"
Leo Chang6fe1f922013-06-07 19:21:24 -070097#include "wlan_hdd_dev_pwr.h"
Jeff Johnson295189b2012-06-20 16:38:30 -070098
99#define g_mode_rates_size (12)
100#define a_mode_rates_size (8)
101#define FREQ_BASE_80211G (2407)
102#define FREQ_BAND_DIFF_80211G (5)
Jeff Johnson04dd8a82012-06-29 20:41:40 -0700103#define MAX_SCAN_SSID 9
Kiet Lamac06e2c2013-10-23 16:25:07 +0530104#define MAX_PENDING_LOG 5
Jeff Johnson295189b2012-06-20 16:38:30 -0700105#define GET_IE_LEN_IN_BSS_DESC(lenInBss) ( lenInBss + sizeof(lenInBss) - \
krunal soni2a6a9062014-02-11 14:14:23 -0800106 ((uintptr_t)OFFSET_OF( tSirBssDescription, ieFields)))
Jeff Johnson295189b2012-06-20 16:38:30 -0700107
108#define HDD2GHZCHAN(freq, chan, flag) { \
109 .band = IEEE80211_BAND_2GHZ, \
110 .center_freq = (freq), \
111 .hw_value = (chan),\
112 .flags = (flag), \
113 .max_antenna_gain = 0 ,\
114 .max_power = 30, \
115}
116
117#define HDD5GHZCHAN(freq, chan, flag) { \
118 .band = IEEE80211_BAND_5GHZ, \
119 .center_freq = (freq), \
120 .hw_value = (chan),\
121 .flags = (flag), \
122 .max_antenna_gain = 0 ,\
123 .max_power = 30, \
124}
125
126#define HDD_G_MODE_RATETAB(rate, rate_id, flag)\
127{\
128 .bitrate = rate, \
129 .hw_value = rate_id, \
130 .flags = flag, \
131}
132
Gopichand Nakkala356fb102013-03-06 12:34:04 +0530133#ifdef WLAN_FEATURE_VOWIFI_11R
134#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
135#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
136#endif
137
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530138#define HDD_CHANNEL_14 14
Dasari Srinivase18b2cf2014-10-28 17:09:42 +0530139#define WLAN_HDD_MAX_FEATURE_SET 8
Naresh Jayaram3180aa42014-02-12 21:47:26 +0530140
Sunil Duttc69bccb2014-05-26 21:30:20 +0530141#ifdef WLAN_FEATURE_LINK_LAYER_STATS
142/*
143 * Used to allocate the size of 4096 for the link layer stats.
144 * The size of 4096 is considered assuming that all data per
145 * respective event fit with in the limit.Please take a call
146 * on the limit based on the data requirements on link layer
147 * statistics.
148 */
149#define LL_STATS_EVENT_BUF_SIZE 4096
150#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +0530151#ifdef WLAN_FEATURE_EXTSCAN
152/*
153 * Used to allocate the size of 4096 for the EXTScan NL data.
154 * The size of 4096 is considered assuming that all data per
155 * respective event fit with in the limit.Please take a call
156 * on the limit based on the data requirements.
157 */
158
159#define EXTSCAN_EVENT_BUF_SIZE 4096
160#define EXTSCAN_MAX_CACHED_RESULTS_PER_IND 32
161#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +0530162
Atul Mittal115287b2014-07-08 13:26:33 +0530163/*EXT TDLS*/
164/*
165 * Used to allocate the size of 4096 for the TDLS.
166 * The size of 4096 is considered assuming that all data per
167 * respective event fit with in the limit.Please take a call
168 * on the limit based on the data requirements on link layer
169 * statistics.
170 */
171#define EXTTDLS_EVENT_BUF_SIZE 4096
172
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530173static const u32 hdd_cipher_suites[] =
Jeff Johnson295189b2012-06-20 16:38:30 -0700174{
175 WLAN_CIPHER_SUITE_WEP40,
176 WLAN_CIPHER_SUITE_WEP104,
177 WLAN_CIPHER_SUITE_TKIP,
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -0800178#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -0700179#define WLAN_CIPHER_SUITE_KRK 0x004096ff /* use for KRK */
180 WLAN_CIPHER_SUITE_KRK,
181 WLAN_CIPHER_SUITE_CCMP,
182#else
183 WLAN_CIPHER_SUITE_CCMP,
184#endif
185#ifdef FEATURE_WLAN_WAPI
186 WLAN_CIPHER_SUITE_SMS4,
187#endif
Chet Lanctot186b5732013-03-18 10:26:30 -0700188#ifdef WLAN_FEATURE_11W
189 WLAN_CIPHER_SUITE_AES_CMAC,
190#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700191};
192
193static inline int is_broadcast_ether_addr(const u8 *addr)
194{
195 return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) &&
196 (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
197}
198
199static struct ieee80211_channel hdd_channels_2_4_GHZ[] =
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530200{
Jeff Johnson295189b2012-06-20 16:38:30 -0700201 HDD2GHZCHAN(2412, 1, 0) ,
202 HDD2GHZCHAN(2417, 2, 0) ,
203 HDD2GHZCHAN(2422, 3, 0) ,
204 HDD2GHZCHAN(2427, 4, 0) ,
205 HDD2GHZCHAN(2432, 5, 0) ,
206 HDD2GHZCHAN(2437, 6, 0) ,
207 HDD2GHZCHAN(2442, 7, 0) ,
208 HDD2GHZCHAN(2447, 8, 0) ,
209 HDD2GHZCHAN(2452, 9, 0) ,
210 HDD2GHZCHAN(2457, 10, 0) ,
211 HDD2GHZCHAN(2462, 11, 0) ,
212 HDD2GHZCHAN(2467, 12, 0) ,
213 HDD2GHZCHAN(2472, 13, 0) ,
214 HDD2GHZCHAN(2484, 14, 0) ,
215};
216
Jeff Johnson295189b2012-06-20 16:38:30 -0700217static struct ieee80211_channel hdd_social_channels_2_4_GHZ[] =
218{
219 HDD2GHZCHAN(2412, 1, 0) ,
220 HDD2GHZCHAN(2437, 6, 0) ,
221 HDD2GHZCHAN(2462, 11, 0) ,
222};
Jeff Johnson295189b2012-06-20 16:38:30 -0700223
224static struct ieee80211_channel hdd_channels_5_GHZ[] =
225{
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -0700226 HDD5GHZCHAN(4920, 240, 0) ,
227 HDD5GHZCHAN(4940, 244, 0) ,
228 HDD5GHZCHAN(4960, 248, 0) ,
229 HDD5GHZCHAN(4980, 252, 0) ,
230 HDD5GHZCHAN(5040, 208, 0) ,
231 HDD5GHZCHAN(5060, 212, 0) ,
232 HDD5GHZCHAN(5080, 216, 0) ,
Jeff Johnson295189b2012-06-20 16:38:30 -0700233 HDD5GHZCHAN(5180, 36, 0) ,
234 HDD5GHZCHAN(5200, 40, 0) ,
235 HDD5GHZCHAN(5220, 44, 0) ,
236 HDD5GHZCHAN(5240, 48, 0) ,
237 HDD5GHZCHAN(5260, 52, 0) ,
238 HDD5GHZCHAN(5280, 56, 0) ,
239 HDD5GHZCHAN(5300, 60, 0) ,
240 HDD5GHZCHAN(5320, 64, 0) ,
241 HDD5GHZCHAN(5500,100, 0) ,
242 HDD5GHZCHAN(5520,104, 0) ,
243 HDD5GHZCHAN(5540,108, 0) ,
244 HDD5GHZCHAN(5560,112, 0) ,
245 HDD5GHZCHAN(5580,116, 0) ,
246 HDD5GHZCHAN(5600,120, 0) ,
247 HDD5GHZCHAN(5620,124, 0) ,
248 HDD5GHZCHAN(5640,128, 0) ,
249 HDD5GHZCHAN(5660,132, 0) ,
250 HDD5GHZCHAN(5680,136, 0) ,
251 HDD5GHZCHAN(5700,140, 0) ,
Leo Chang80de3c22013-11-26 10:52:12 -0800252#ifdef FEATURE_WLAN_CH144
253 HDD5GHZCHAN(5720,144, 0) ,
254#endif /* FEATURE_WLAN_CH144 */
Jeff Johnson295189b2012-06-20 16:38:30 -0700255 HDD5GHZCHAN(5745,149, 0) ,
256 HDD5GHZCHAN(5765,153, 0) ,
257 HDD5GHZCHAN(5785,157, 0) ,
258 HDD5GHZCHAN(5805,161, 0) ,
259 HDD5GHZCHAN(5825,165, 0) ,
260};
261
262static struct ieee80211_rate g_mode_rates[] =
263{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530264 HDD_G_MODE_RATETAB(10, 0x1, 0),
265 HDD_G_MODE_RATETAB(20, 0x2, 0),
266 HDD_G_MODE_RATETAB(55, 0x4, 0),
267 HDD_G_MODE_RATETAB(110, 0x8, 0),
268 HDD_G_MODE_RATETAB(60, 0x10, 0),
269 HDD_G_MODE_RATETAB(90, 0x20, 0),
270 HDD_G_MODE_RATETAB(120, 0x40, 0),
271 HDD_G_MODE_RATETAB(180, 0x80, 0),
272 HDD_G_MODE_RATETAB(240, 0x100, 0),
273 HDD_G_MODE_RATETAB(360, 0x200, 0),
274 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700275 HDD_G_MODE_RATETAB(540, 0x800, 0),
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530276};
Jeff Johnson295189b2012-06-20 16:38:30 -0700277
278static struct ieee80211_rate a_mode_rates[] =
279{
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530280 HDD_G_MODE_RATETAB(60, 0x10, 0),
281 HDD_G_MODE_RATETAB(90, 0x20, 0),
282 HDD_G_MODE_RATETAB(120, 0x40, 0),
283 HDD_G_MODE_RATETAB(180, 0x80, 0),
284 HDD_G_MODE_RATETAB(240, 0x100, 0),
285 HDD_G_MODE_RATETAB(360, 0x200, 0),
286 HDD_G_MODE_RATETAB(480, 0x400, 0),
Jeff Johnson295189b2012-06-20 16:38:30 -0700287 HDD_G_MODE_RATETAB(540, 0x800, 0),
288};
289
290static struct ieee80211_supported_band wlan_hdd_band_2_4_GHZ =
291{
292 .channels = hdd_channels_2_4_GHZ,
293 .n_channels = ARRAY_SIZE(hdd_channels_2_4_GHZ),
294 .band = IEEE80211_BAND_2GHZ,
295 .bitrates = g_mode_rates,
296 .n_bitrates = g_mode_rates_size,
297 .ht_cap.ht_supported = 1,
298 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
299 | IEEE80211_HT_CAP_GRN_FLD
300 | IEEE80211_HT_CAP_DSSSCCK40
301 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
302 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
303 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
304 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
305 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
306 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
307};
308
Jeff Johnson295189b2012-06-20 16:38:30 -0700309static struct ieee80211_supported_band wlan_hdd_band_p2p_2_4_GHZ =
310{
311 .channels = hdd_social_channels_2_4_GHZ,
312 .n_channels = ARRAY_SIZE(hdd_social_channels_2_4_GHZ),
313 .band = IEEE80211_BAND_2GHZ,
314 .bitrates = g_mode_rates,
315 .n_bitrates = g_mode_rates_size,
316 .ht_cap.ht_supported = 1,
317 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
318 | IEEE80211_HT_CAP_GRN_FLD
319 | IEEE80211_HT_CAP_DSSSCCK40
320 | IEEE80211_HT_CAP_LSIG_TXOP_PROT,
321 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
322 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
323 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
324 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
325 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
326};
Jeff Johnson295189b2012-06-20 16:38:30 -0700327
328static struct ieee80211_supported_band wlan_hdd_band_5_GHZ =
329{
330 .channels = hdd_channels_5_GHZ,
331 .n_channels = ARRAY_SIZE(hdd_channels_5_GHZ),
332 .band = IEEE80211_BAND_5GHZ,
333 .bitrates = a_mode_rates,
334 .n_bitrates = a_mode_rates_size,
335 .ht_cap.ht_supported = 1,
336 .ht_cap.cap = IEEE80211_HT_CAP_SGI_20
337 | IEEE80211_HT_CAP_GRN_FLD
338 | IEEE80211_HT_CAP_DSSSCCK40
339 | IEEE80211_HT_CAP_LSIG_TXOP_PROT
340 | IEEE80211_HT_CAP_SGI_40
341 | IEEE80211_HT_CAP_SUP_WIDTH_20_40,
342 .ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
343 .ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16,
344 .ht_cap.mcs.rx_mask = { 0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
345 .ht_cap.mcs.rx_highest = cpu_to_le16( 72 ),
346 .ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED,
347};
348
Gopichand Nakkala747461f2013-04-24 19:24:45 +0530349/* This structure contain information what kind of frame are expected in
Jeff Johnson295189b2012-06-20 16:38:30 -0700350 TX/RX direction for each kind of interface */
351static const struct ieee80211_txrx_stypes
352wlan_hdd_txrx_stypes[NUM_NL80211_IFTYPES] = {
353 [NL80211_IFTYPE_STATION] = {
354 .tx = 0xffff,
355 .rx = BIT(SIR_MAC_MGMT_ACTION) |
356 BIT(SIR_MAC_MGMT_PROBE_REQ),
357 },
358 [NL80211_IFTYPE_AP] = {
359 .tx = 0xffff,
360 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
361 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
362 BIT(SIR_MAC_MGMT_PROBE_REQ) |
363 BIT(SIR_MAC_MGMT_DISASSOC) |
364 BIT(SIR_MAC_MGMT_AUTH) |
365 BIT(SIR_MAC_MGMT_DEAUTH) |
366 BIT(SIR_MAC_MGMT_ACTION),
367 },
Jeff Johnsonbc006202013-04-29 14:05:30 -0700368 [NL80211_IFTYPE_ADHOC] = {
369 .tx = 0xffff,
370 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
371 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
372 BIT(SIR_MAC_MGMT_PROBE_REQ) |
373 BIT(SIR_MAC_MGMT_DISASSOC) |
374 BIT(SIR_MAC_MGMT_AUTH) |
375 BIT(SIR_MAC_MGMT_DEAUTH) |
376 BIT(SIR_MAC_MGMT_ACTION),
377 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700378 [NL80211_IFTYPE_P2P_CLIENT] = {
379 .tx = 0xffff,
380 .rx = BIT(SIR_MAC_MGMT_ACTION) |
381 BIT(SIR_MAC_MGMT_PROBE_REQ),
382 },
383 [NL80211_IFTYPE_P2P_GO] = {
384 /* This is also same as for SoftAP */
385 .tx = 0xffff,
386 .rx = BIT(SIR_MAC_MGMT_ASSOC_REQ) |
387 BIT(SIR_MAC_MGMT_REASSOC_REQ) |
388 BIT(SIR_MAC_MGMT_PROBE_REQ) |
389 BIT(SIR_MAC_MGMT_DISASSOC) |
390 BIT(SIR_MAC_MGMT_AUTH) |
391 BIT(SIR_MAC_MGMT_DEAUTH) |
392 BIT(SIR_MAC_MGMT_ACTION),
393 },
Jeff Johnson295189b2012-06-20 16:38:30 -0700394};
395
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800396#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800397static const struct ieee80211_iface_limit
398wlan_hdd_iface_limit[] = {
399 {
Sunil Ravia72c3992013-01-31 06:12:22 -0800400 /* max = 3 ; Our driver create two interfaces during driver init
401 * wlan0 and p2p0 interfaces. p2p0 is considered as station
402 * interface until a group is formed. In JB architecture, once the
403 * group is formed, interface type of p2p0 is changed to P2P GO or
404 * Client.
405 * When supplicant remove the group, it first issue a set interface
406 * cmd to change the mode back to Station. In JB this works fine as
407 * we advertize two station type interface during driver init.
408 * Some vendors create separate interface for P2P GO/Client,
409 * after group formation(Third one). But while group remove
410 * supplicant first tries to change the mode(3rd interface) to STATION
411 * But as we advertized only two sta type interfaces nl80211 was
412 * returning error for the third one which was leading to failure in
413 * delete interface. Ideally while removing the group, supplicant
414 * should not try to change the 3rd interface mode to Station type.
415 * Till we get a fix in wpa_supplicant, we advertize max STA
416 * interface type to 3
417 */
418 .max = 3,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800419 .types = BIT(NL80211_IFTYPE_STATION),
420 },
421 {
422 .max = 1,
Jeff Johnsonbc006202013-04-29 14:05:30 -0700423 .types = BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP),
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800424 },
425 {
426 .max = 1,
427 .types = BIT(NL80211_IFTYPE_P2P_GO) |
428 BIT(NL80211_IFTYPE_P2P_CLIENT),
429 },
430};
431
432/* By default, only single channel concurrency is allowed */
433static struct ieee80211_iface_combination
434wlan_hdd_iface_combination = {
435 .limits = wlan_hdd_iface_limit,
436 .num_different_channels = 1,
Sunil Ravia72c3992013-01-31 06:12:22 -0800437 /*
438 * max = WLAN_MAX_INTERFACES ; JellyBean architecture creates wlan0
439 * and p2p0 interfaces during driver init
440 * Some vendors create separate interface for P2P operations.
441 * wlan0: STA interface
442 * p2p0: P2P Device interface, action frames goes
443 * through this interface.
444 * p2p-xx: P2P interface, After GO negotiation this interface is
445 * created for p2p operations(GO/CLIENT interface).
446 */
447 .max_interfaces = WLAN_MAX_INTERFACES,
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800448 .n_limits = ARRAY_SIZE(wlan_hdd_iface_limit),
449 .beacon_int_infra_match = false,
450};
451#endif
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -0800452
Jeff Johnson295189b2012-06-20 16:38:30 -0700453static struct cfg80211_ops wlan_hdd_cfg80211_ops;
454
455/* Data rate 100KBPS based on IE Index */
456struct index_data_rate_type
457{
458 v_U8_t beacon_rate_index;
459 v_U16_t supported_rate[4];
460};
461
462/* 11B, 11G Rate table include Basic rate and Extended rate
463 The IDX field is the rate index
464 The HI field is the rate when RSSI is strong or being ignored
465 (in this case we report actual rate)
466 The MID field is the rate when RSSI is moderate
467 (in this case we cap 11b rates at 5.5 and 11g rates at 24)
468 The LO field is the rate when RSSI is low
469 (in this case we don't report rates, actual current rate used)
470 */
471static const struct
472{
473 v_U8_t beacon_rate_index;
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700474 v_U16_t supported_rate[4];
Jeff Johnson295189b2012-06-20 16:38:30 -0700475} supported_data_rate[] =
476{
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -0700477/* IDX HI HM LM LO (RSSI-based index */
478 {2, { 10, 10, 10, 0}},
479 {4, { 20, 20, 10, 0}},
480 {11, { 55, 20, 10, 0}},
481 {12, { 60, 55, 20, 0}},
482 {18, { 90, 55, 20, 0}},
483 {22, {110, 55, 20, 0}},
484 {24, {120, 90, 60, 0}},
485 {36, {180, 120, 60, 0}},
486 {44, {220, 180, 60, 0}},
487 {48, {240, 180, 90, 0}},
488 {66, {330, 180, 90, 0}},
489 {72, {360, 240, 90, 0}},
490 {96, {480, 240, 120, 0}},
491 {108, {540, 240, 120, 0}}
Jeff Johnson295189b2012-06-20 16:38:30 -0700492};
493
494/* MCS Based rate table */
495static struct index_data_rate_type supported_mcs_rate[] =
496{
497/* MCS L20 L40 S20 S40 */
498 {0, {65, 135, 72, 150}},
499 {1, {130, 270, 144, 300}},
500 {2, {195, 405, 217, 450}},
501 {3, {260, 540, 289, 600}},
502 {4, {390, 810, 433, 900}},
503 {5, {520, 1080, 578, 1200}},
504 {6, {585, 1215, 650, 1350}},
505 {7, {650, 1350, 722, 1500}}
506};
507
Leo Chang6f8870f2013-03-26 18:11:36 -0700508#ifdef WLAN_FEATURE_11AC
509
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530510#define DATA_RATE_11AC_MCS_MASK 0x03
Leo Chang6f8870f2013-03-26 18:11:36 -0700511
512struct index_vht_data_rate_type
513{
514 v_U8_t beacon_rate_index;
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530515 v_U16_t supported_VHT80_rate[2];
516 v_U16_t supported_VHT40_rate[2];
517 v_U16_t supported_VHT20_rate[2];
Leo Chang6f8870f2013-03-26 18:11:36 -0700518};
519
520typedef enum
521{
522 DATA_RATE_11AC_MAX_MCS_7,
523 DATA_RATE_11AC_MAX_MCS_8,
524 DATA_RATE_11AC_MAX_MCS_9,
525 DATA_RATE_11AC_MAX_MCS_NA
526} eDataRate11ACMaxMcs;
527
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +0530528/* SSID broadcast type */
529typedef enum eSSIDBcastType
530{
531 eBCAST_UNKNOWN = 0,
532 eBCAST_NORMAL = 1,
533 eBCAST_HIDDEN = 2,
534} tSSIDBcastType;
535
Leo Chang6f8870f2013-03-26 18:11:36 -0700536/* MCS Based VHT rate table */
537static struct index_vht_data_rate_type supported_vht_mcs_rate[] =
538{
Gopichand Nakkala4c705372013-04-24 13:20:33 +0530539/* MCS L80 S80 L40 S40 L20 S40*/
540 {0, {293, 325}, {135, 150}, {65, 72}},
541 {1, {585, 650}, {270, 300}, {130, 144}},
542 {2, {878, 975}, {405, 450}, {195, 217}},
543 {3, {1170, 1300}, {540, 600}, {260, 289}},
544 {4, {1755, 1950}, {810, 900}, {390, 433}},
545 {5, {2340, 2600}, {1080, 1200}, {520, 578}},
546 {6, {2633, 2925}, {1215, 1350}, {585, 650}},
547 {7, {2925, 3250}, {1350, 1500}, {650, 722}},
548 {8, {3510, 3900}, {1620, 1800}, {780, 867}},
549 {9, {3900, 4333}, {1800, 2000}, {780, 867}}
Leo Chang6f8870f2013-03-26 18:11:36 -0700550};
551#endif /* WLAN_FEATURE_11AC */
552
c_hpothu79aab322014-07-14 21:11:01 +0530553/*array index points to MCS and array value points respective rssi*/
554static int rssiMcsTbl[][10] =
555{
556/*MCS 0 1 2 3 4 5 6 7 8 9*/
557 {-82, -79, -77, -74, -70, -66, -65, -64, -59, -57}, //20
558 {-79, -76, -74, -71, -67, -63, -62, -61, -56, -54}, //40
559 {-76, -73, -71, -68, -64, -60, -59, -58, -53, -51} //80
560};
561
Jeff Johnson295189b2012-06-20 16:38:30 -0700562extern struct net_device_ops net_ops_struct;
Dasari Srinivas7875a302014-09-26 17:50:57 +0530563#ifdef FEATURE_WLAN_SCAN_PNO
564static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter);
565#endif
Jeff Johnson295189b2012-06-20 16:38:30 -0700566
Leo Chang9056f462013-08-01 19:21:11 -0700567#ifdef WLAN_NL80211_TESTMODE
568enum wlan_hdd_tm_attr
569{
570 WLAN_HDD_TM_ATTR_INVALID = 0,
571 WLAN_HDD_TM_ATTR_CMD = 1,
572 WLAN_HDD_TM_ATTR_DATA = 2,
573 WLAN_HDD_TM_ATTR_TYPE = 3,
574 /* keep last */
575 WLAN_HDD_TM_ATTR_AFTER_LAST,
576 WLAN_HDD_TM_ATTR_MAX = WLAN_HDD_TM_ATTR_AFTER_LAST - 1,
577};
578
579enum wlan_hdd_tm_cmd
580{
581 WLAN_HDD_TM_CMD_WLAN_HB = 1,
582};
583
584#define WLAN_HDD_TM_DATA_MAX_LEN 5000
585
586static const struct nla_policy wlan_hdd_tm_policy[WLAN_HDD_TM_ATTR_MAX + 1] =
587{
588 [WLAN_HDD_TM_ATTR_CMD] = { .type = NLA_U32 },
589 [WLAN_HDD_TM_ATTR_DATA] = { .type = NLA_BINARY,
590 .len = WLAN_HDD_TM_DATA_MAX_LEN },
591};
592#endif /* WLAN_NL80211_TESTMODE */
593
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800594#ifdef FEATURE_WLAN_CH_AVOID
595/*
596 * FUNCTION: wlan_hdd_send_avoid_freq_event
597 * This is called when wlan driver needs to send vendor specific
598 * avoid frequency range event to userspace
599 */
600int wlan_hdd_send_avoid_freq_event(hdd_context_t *pHddCtx,
601 tHddAvoidFreqList *pAvoidFreqList)
602{
603 struct sk_buff *vendor_event;
604
605 ENTER();
606
607 if (!pHddCtx)
608 {
609 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
610 "%s: HDD context is null", __func__);
611 return -1;
612 }
613
614 if (!pAvoidFreqList)
615 {
616 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
617 "%s: pAvoidFreqList is null", __func__);
618 return -1;
619 }
620
621 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530622#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
623 NULL,
624#endif
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800625 sizeof(tHddAvoidFreqList),
Sunil Duttc69bccb2014-05-26 21:30:20 +0530626 QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX,
Rajesh Chauhan98a31f82014-01-06 20:15:25 -0800627 GFP_KERNEL);
628 if (!vendor_event)
629 {
630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
631 "%s: cfg80211_vendor_event_alloc failed", __func__);
632 return -1;
633 }
634
635 memcpy(skb_put(vendor_event, sizeof(tHddAvoidFreqList)),
636 (void *)pAvoidFreqList, sizeof(tHddAvoidFreqList));
637
638 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
639
640 EXIT();
641 return 0;
642}
643#endif /* FEATURE_WLAN_CH_AVOID */
644
Srinivas Dasari030bad32015-02-18 23:23:54 +0530645/*
646 * FUNCTION: __wlan_hdd_cfg80211_nan_request
647 * This is called when wlan driver needs to send vendor specific
648 * nan request event.
649 */
650static int __wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
651 struct wireless_dev *wdev,
652 const void *data, int data_len)
653{
654 tNanRequestReq nan_req;
655 VOS_STATUS status;
656 int ret_val = -1;
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530657 struct net_device *dev = wdev->netdev;
658 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
659 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530660 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
661
662 if (0 == data_len)
663 {
664 hddLog(VOS_TRACE_LEVEL_ERROR,
665 FL("NAN - Invalid Request, length = 0"));
666 return ret_val;
667 }
668
669 if (NULL == data)
670 {
671 hddLog(VOS_TRACE_LEVEL_ERROR,
672 FL("NAN - Invalid Request, data is NULL"));
673 return ret_val;
674 }
675
676 status = wlan_hdd_validate_context(pHddCtx);
677 if (0 != status)
678 {
679 hddLog(VOS_TRACE_LEVEL_ERROR,
680 FL("HDD context is not valid"));
681 return -EINVAL;
682 }
683
684 hddLog(LOG1, FL("Received NAN command"));
685 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
686 (tANI_U8 *)data, data_len);
687
688 /* check the NAN Capability */
689 if (TRUE != sme_IsFeatureSupportedByFW(NAN))
690 {
691 hddLog(VOS_TRACE_LEVEL_ERROR,
692 FL("NAN is not supported by Firmware"));
693 return -EINVAL;
694 }
695
696 nan_req.request_data_len = data_len;
697 nan_req.request_data = data;
698
Srinivas Dasaria3f11c02015-03-20 13:15:20 +0530699 status = sme_NanRequest(hHal, &nan_req, pAdapter->sessionId);
Srinivas Dasari030bad32015-02-18 23:23:54 +0530700 if (VOS_STATUS_SUCCESS == status)
701 {
702 ret_val = 0;
703 }
704 return ret_val;
705}
706
707/*
708 * FUNCTION: wlan_hdd_cfg80211_nan_request
709 * Wrapper to protect the nan vendor command from ssr
710 */
711static int wlan_hdd_cfg80211_nan_request(struct wiphy *wiphy,
712 struct wireless_dev *wdev,
713 const void *data, int data_len)
714{
715 int ret;
716
717 vos_ssr_protect(__func__);
718 ret = __wlan_hdd_cfg80211_nan_request(wiphy, wdev, data, data_len);
719 vos_ssr_unprotect(__func__);
720
721 return ret;
722}
723
724/*
725 * FUNCTION: wlan_hdd_cfg80211_nan_callback
726 * This is a callback function and it gets called
727 * when we need to report nan response event to
728 * upper layers.
729 */
730static void wlan_hdd_cfg80211_nan_callback(void* ctx, tSirNanEvent* msg)
731{
732 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
733 struct sk_buff *vendor_event;
734 int status;
735 tSirNanEvent *data;
736
737 ENTER();
738 if (NULL == msg)
739 {
740 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
741 FL(" msg received here is null"));
742 return;
743 }
744 data = msg;
745
746 status = wlan_hdd_validate_context(pHddCtx);
747
748 if (0 != status)
749 {
750 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
751 FL("HDD context is not valid"));
752 return;
753 }
754
755 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +0530756#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
757 NULL,
758#endif
Srinivas Dasari030bad32015-02-18 23:23:54 +0530759 data->event_data_len +
760 NLMSG_HDRLEN,
761 QCA_NL80211_VENDOR_SUBCMD_NAN_INDEX,
762 GFP_KERNEL);
763
764 if (!vendor_event)
765 {
766 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
767 FL("cfg80211_vendor_event_alloc failed"));
768 return;
769 }
770 if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NAN,
771 data->event_data_len, data->event_data))
772 {
773 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
774 FL("QCA_WLAN_VENDOR_ATTR_NAN put fail"));
775 kfree_skb(vendor_event);
776 return;
777 }
778 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
779 EXIT();
780}
781
782/*
783 * FUNCTION: wlan_hdd_cfg80211_nan_init
784 * This function is called to register the callback to sme layer
785 */
786inline void wlan_hdd_cfg80211_nan_init(hdd_context_t *pHddCtx)
787{
788 sme_NanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_nan_callback);
789}
790
791
Sunil Duttc69bccb2014-05-26 21:30:20 +0530792#ifdef WLAN_FEATURE_LINK_LAYER_STATS
793
794static v_BOOL_t put_wifi_rate_stat( tpSirWifiRateStat stats,
795 struct sk_buff *vendor_event)
796{
797 if (nla_put_u8(vendor_event,
798 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE,
799 stats->rate.preamble) ||
800 nla_put_u8(vendor_event,
801 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS,
802 stats->rate.nss) ||
803 nla_put_u8(vendor_event,
804 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW,
805 stats->rate.bw) ||
806 nla_put_u8(vendor_event,
807 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX,
808 stats->rate.rateMcsIdx) ||
809 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE,
810 stats->rate.bitrate ) ||
811 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU,
812 stats->txMpdu ) ||
813 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU,
814 stats->rxMpdu ) ||
815 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST,
816 stats->mpduLost ) ||
817 nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES,
818 stats->retries) ||
819 nla_put_u32(vendor_event,
820 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT,
821 stats->retriesShort ) ||
822 nla_put_u32(vendor_event,
823 QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG,
824 stats->retriesLong))
825 {
826 hddLog(VOS_TRACE_LEVEL_ERROR,
827 FL("QCA_WLAN_VENDOR_ATTR put fail"));
828 return FALSE;
829 }
830 return TRUE;
831}
832
833static v_BOOL_t put_wifi_peer_info( tpSirWifiPeerInfo stats,
834 struct sk_buff *vendor_event)
835{
836 u32 i = 0;
837 struct nlattr *rateInfo;
838 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE,
839 stats->type) ||
840 nla_put(vendor_event,
841 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS,
842 VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) ||
843 nla_put_u32(vendor_event,
844 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES,
845 stats->capabilities) ||
846 nla_put_u32(vendor_event,
847 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES,
848 stats->numRate))
849 {
850 hddLog(VOS_TRACE_LEVEL_ERROR,
851 FL("QCA_WLAN_VENDOR_ATTR put fail"));
852 goto error;
853 }
854
855 rateInfo = nla_nest_start(vendor_event,
856 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530857 if(!rateInfo)
858 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530859 for (i = 0; i < stats->numRate; i++)
860 {
861 struct nlattr *rates;
862 tpSirWifiRateStat pRateStats = (tpSirWifiRateStat )((uint8 *)
863 stats->rateStats +
864 (i * sizeof(tSirWifiRateStat)));
865 rates = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +0530866 if(!rates)
867 return FALSE;
Sunil Duttc69bccb2014-05-26 21:30:20 +0530868
869 if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event))
870 {
871 hddLog(VOS_TRACE_LEVEL_ERROR,
872 FL("QCA_WLAN_VENDOR_ATTR put fail"));
873 return FALSE;
874 }
875 nla_nest_end(vendor_event, rates);
876 }
877 nla_nest_end(vendor_event, rateInfo);
878
879 return TRUE;
880error:
881 return FALSE;
882}
883
884static v_BOOL_t put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats,
885 struct sk_buff *vendor_event)
886{
887 if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC,
888 stats->ac ) ||
889 nla_put_u32(vendor_event,
890 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU,
891 stats->txMpdu ) ||
892 nla_put_u32(vendor_event,
893 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU,
894 stats->rxMpdu ) ||
895 nla_put_u32(vendor_event,
896 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST,
897 stats->txMcast ) ||
898 nla_put_u32(vendor_event,
899 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST,
900 stats->rxMcast ) ||
901 nla_put_u32(vendor_event,
902 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU,
903 stats->rxAmpdu ) ||
904 nla_put_u32(vendor_event,
905 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU,
906 stats->txAmpdu ) ||
907 nla_put_u32(vendor_event,
908 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST,
909 stats->mpduLost )||
910 nla_put_u32(vendor_event,
911 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES,
912 stats->retries ) ||
913 nla_put_u32(vendor_event,
914 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT,
915 stats->retriesShort ) ||
916 nla_put_u32(vendor_event,
917 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG,
918 stats->retriesLong ) ||
919 nla_put_u32(vendor_event,
920 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN,
921 stats->contentionTimeMin ) ||
922 nla_put_u32(vendor_event,
923 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX,
924 stats->contentionTimeMax ) ||
925 nla_put_u32(vendor_event,
926 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG,
927 stats->contentionTimeAvg ) ||
928 nla_put_u32(vendor_event,
929 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES,
930 stats->contentionNumSamples ))
931 {
932 hddLog(VOS_TRACE_LEVEL_ERROR,
933 FL("QCA_WLAN_VENDOR_ATTR put fail") );
934 return FALSE;
935 }
936 return TRUE;
937}
938
939static v_BOOL_t put_wifi_interface_info(tpSirWifiInterfaceInfo stats,
940 struct sk_buff *vendor_event)
941{
Dino Myclec8f3f332014-07-21 16:48:27 +0530942 if (nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530943 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, stats->mode ) ||
944 nla_put(vendor_event,
945 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR,
946 VOS_MAC_ADDR_SIZE, stats->macAddr) ||
947 nla_put_u32(vendor_event,
948 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE,
949 stats->state ) ||
950 nla_put_u32(vendor_event,
951 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING,
952 stats->roaming ) ||
953 nla_put_u32(vendor_event,
954 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES,
955 stats->capabilities ) ||
956 nla_put(vendor_event,
957 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID,
958 strlen(stats->ssid), stats->ssid) ||
959 nla_put(vendor_event,
960 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID,
961 WNI_CFG_BSSID_LEN, stats->bssid) ||
962 nla_put(vendor_event,
963 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR,
964 WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) ||
965 nla_put(vendor_event,
966 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR,
967 WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)
968 )
969 {
970 hddLog(VOS_TRACE_LEVEL_ERROR,
971 FL("QCA_WLAN_VENDOR_ATTR put fail") );
972 return FALSE;
973 }
974 return TRUE;
975}
976
Dino Mycle3b9536d2014-07-09 22:05:24 +0530977static v_BOOL_t put_wifi_iface_stats(hdd_adapter_t *pAdapter,
978 tpSirWifiIfaceStat pWifiIfaceStat,
Sunil Duttc69bccb2014-05-26 21:30:20 +0530979 struct sk_buff *vendor_event)
980{
981 int i = 0;
982 struct nlattr *wmmInfo;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530983 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
984 WLANTL_InterfaceStatsType *pWifiIfaceStatTL = NULL;
Srinivas Dasaria8a304f2014-11-15 16:13:37 +0530985 tSirWifiWmmAcStat accessclassStats;
Dino Mycle3b9536d2014-07-09 22:05:24 +0530986
Sunil Duttc69bccb2014-05-26 21:30:20 +0530987 if (FALSE == put_wifi_interface_info(
988 &pWifiIfaceStat->info,
989 vendor_event))
990 {
991 hddLog(VOS_TRACE_LEVEL_ERROR,
992 FL("QCA_WLAN_VENDOR_ATTR put fail") );
993 return FALSE;
994
995 }
Dino Mycle3b9536d2014-07-09 22:05:24 +0530996 pWifiIfaceStatTL = (WLANTL_InterfaceStatsType *)
997 vos_mem_malloc(sizeof(WLANTL_InterfaceStatsType));
998 if (NULL == pWifiIfaceStatTL)
999 {
1000 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
1001 return FALSE;
1002 }
1003
Srinivas Dasaria8a304f2014-11-15 16:13:37 +05301004 accessclassStats = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK];
1005 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK] =
1006 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE];
1007 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE] = accessclassStats;
1008
1009 accessclassStats.ac = pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac;
1010 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].ac =
1011 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac;
1012 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].ac = accessclassStats.ac;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301013
1014 if ( pWifiIfaceStat->info.state == WIFI_ASSOCIATED)
1015 {
1016 if (VOS_STATUS_SUCCESS ==
1017 WLANTL_CollectInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1018 pHddStaCtx->conn_info.staId[0], pWifiIfaceStatTL))
1019 {
1020 /* mgmtRx, MgmtActionRx, rxMcast, rxMpdu, rxAmpdu, rssiData are
1021 * obtained from TL structure
1022 */
1023
1024 pWifiIfaceStat->mgmtRx = pWifiIfaceStat->beaconRx +
1025 pWifiIfaceStatTL->mgmtRx;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301026 pWifiIfaceStat->rssiData = pWifiIfaceStatTL->rssiData;
1027
Srinivas Dasari98947432014-11-07 19:41:24 +05301028 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMcast
1029 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMcast;
1030 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMcast
1031 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMcast;
1032 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMcast
1033 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMcast;
1034 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMcast
1035 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMcast;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301036
Srinivas Dasari98947432014-11-07 19:41:24 +05301037 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxMpdu
1038 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxMpdu;
1039 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxMpdu
1040 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxMpdu;
1041 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxMpdu
1042 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxMpdu;
1043 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxMpdu
1044 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxMpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301045
Srinivas Dasari98947432014-11-07 19:41:24 +05301046 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].rxAmpdu
1047 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VO].rxAmpdu;
1048 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].rxAmpdu
1049 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_VI].rxAmpdu;
1050 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].rxAmpdu
1051 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BE].rxAmpdu;
1052 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].rxAmpdu
1053 = pWifiIfaceStatTL->accessCategoryStats[WLANTL_AC_BK].rxAmpdu;
Dino Mycle3b9536d2014-07-09 22:05:24 +05301054 }
1055 else
1056 {
1057 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in getting stats from TL"));
1058 }
1059
Dino Mycle3b9536d2014-07-09 22:05:24 +05301060 pWifiIfaceStat->AccessclassStats[WIFI_AC_VO].txMcast =
1061 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO];
1062 pWifiIfaceStat->AccessclassStats[WIFI_AC_VI].txMcast =
1063 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI];
1064 pWifiIfaceStat->AccessclassStats[WIFI_AC_BE].txMcast =
1065 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE];
1066 pWifiIfaceStat->AccessclassStats[WIFI_AC_BK].txMcast =
1067 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK];
1068 }
1069 else
1070 {
1071 hddLog(VOS_TRACE_LEVEL_INFO, FL("Interface not Associated"));
1072 }
1073
1074
Sunil Duttc69bccb2014-05-26 21:30:20 +05301075
1076 if (nla_put_u32(vendor_event,
1077 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX,
1078 pWifiIfaceStat->beaconRx) ||
1079 nla_put_u32(vendor_event,
1080 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX,
1081 pWifiIfaceStat->mgmtRx) ||
1082 nla_put_u32(vendor_event,
1083 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX,
1084 pWifiIfaceStat->mgmtActionRx) ||
1085 nla_put_u32(vendor_event,
1086 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX,
1087 pWifiIfaceStat->mgmtActionTx) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301088 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301089 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT,
1090 pWifiIfaceStat->rssiMgmt) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301091 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301092 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA,
1093 pWifiIfaceStat->rssiData) ||
Dino Mycle3b9536d2014-07-09 22:05:24 +05301094 nla_put_s32(vendor_event,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301095 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK,
1096 pWifiIfaceStat->rssiAck))
1097 {
1098 hddLog(VOS_TRACE_LEVEL_ERROR,
1099 FL("QCA_WLAN_VENDOR_ATTR put fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301100 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301101 return FALSE;
1102 }
1103
1104 wmmInfo = nla_nest_start(vendor_event,
1105 QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301106 if(!wmmInfo)
1107 {
1108 vos_mem_free(pWifiIfaceStatTL);
1109 return FALSE;
1110 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301111 for (i = 0; i < WIFI_AC_MAX; i++)
1112 {
1113 struct nlattr *wmmStats;
1114 wmmStats = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301115 if(!wmmStats)
1116 {
1117 vos_mem_free(pWifiIfaceStatTL);
1118 return FALSE;
1119 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301120 if (FALSE == put_wifi_wmm_ac_stat(
1121 &pWifiIfaceStat->AccessclassStats[i],
1122 vendor_event))
1123 {
1124 hddLog(VOS_TRACE_LEVEL_ERROR,
1125 FL("QCA_WLAN_VENDOR_ATTR put Fail"));
Dino Mycle3b9536d2014-07-09 22:05:24 +05301126 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301127 return FALSE;
1128 }
1129
1130 nla_nest_end(vendor_event, wmmStats);
1131 }
1132 nla_nest_end(vendor_event, wmmInfo);
Dino Mycle3b9536d2014-07-09 22:05:24 +05301133 vos_mem_free(pWifiIfaceStatTL);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301134 return TRUE;
1135}
1136
1137static tSirWifiInterfaceMode
1138 hdd_map_device_to_ll_iface_mode ( int deviceMode )
1139{
1140 switch (deviceMode)
1141 {
1142 case WLAN_HDD_INFRA_STATION:
1143 return WIFI_INTERFACE_STA;
1144 case WLAN_HDD_SOFTAP:
1145 return WIFI_INTERFACE_SOFTAP;
1146 case WLAN_HDD_P2P_CLIENT:
1147 return WIFI_INTERFACE_P2P_CLIENT;
1148 case WLAN_HDD_P2P_GO:
1149 return WIFI_INTERFACE_P2P_GO;
1150 case WLAN_HDD_IBSS:
1151 return WIFI_INTERFACE_IBSS;
1152 default:
Dino Myclec8f3f332014-07-21 16:48:27 +05301153 return WIFI_INTERFACE_UNKNOWN;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301154 }
1155}
1156
1157static v_BOOL_t hdd_get_interface_info(hdd_adapter_t *pAdapter,
1158 tpSirWifiInterfaceInfo pInfo)
1159{
1160 v_U8_t *staMac = NULL;
1161 hdd_station_ctx_t *pHddStaCtx;
1162 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
1163 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1164
1165 pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode);
1166
1167 vos_mem_copy(pInfo->macAddr,
1168 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
1169
1170 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
1171 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
1172 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)))
1173 {
1174 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1175 if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState)
1176 {
1177 pInfo->state = WIFI_DISCONNECTED;
1178 }
1179 if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState)
1180 {
1181 hddLog(VOS_TRACE_LEVEL_ERROR,
1182 "%s: Session ID %d, Connection is in progress", __func__,
1183 pAdapter->sessionId);
1184 pInfo->state = WIFI_ASSOCIATING;
1185 }
1186 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
1187 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
1188 {
1189 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
1190 hddLog(VOS_TRACE_LEVEL_ERROR,
1191 "%s: client " MAC_ADDRESS_STR
1192 " is in the middle of WPS/EAPOL exchange.", __func__,
1193 MAC_ADDR_ARRAY(staMac));
1194 pInfo->state = WIFI_AUTHENTICATING;
1195 }
1196 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
1197 {
1198 pInfo->state = WIFI_ASSOCIATED;
1199 vos_mem_copy(pInfo->bssid,
1200 &pHddStaCtx->conn_info.bssId, WNI_CFG_BSSID_LEN);
1201 vos_mem_copy(pInfo->ssid,
1202 pHddStaCtx->conn_info.SSID.SSID.ssId,
1203 pHddStaCtx->conn_info.SSID.SSID.length);
1204 //NULL Terminate the string.
1205 pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0;
1206 }
1207 }
1208 vos_mem_copy(pInfo->countryStr,
1209 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1210
1211 vos_mem_copy(pInfo->apCountryStr,
1212 pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN);
1213
1214 return TRUE;
1215}
1216
1217/*
1218 * hdd_link_layer_process_peer_stats () - This function is called after
1219 * receiving Link Layer Peer statistics from FW.This function converts
1220 * the firmware data to the NL data and sends the same to the kernel/upper
1221 * layers.
1222 */
1223static v_VOID_t hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter,
1224 v_VOID_t *pData)
1225{
1226 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1227 tpSirWifiRateStat pWifiRateStat;
1228 tpSirWifiPeerStat pWifiPeerStat;
1229 tpSirWifiPeerInfo pWifiPeerInfo;
1230 struct nlattr *peerInfo;
1231 struct sk_buff *vendor_event;
1232 int status, i;
1233
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301234 ENTER();
1235
Sunil Duttc69bccb2014-05-26 21:30:20 +05301236 status = wlan_hdd_validate_context(pHddCtx);
1237 if (0 != status)
1238 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301239 return;
1240 }
1241
1242 pWifiPeerStat = (tpSirWifiPeerStat) pData;
1243
1244 hddLog(VOS_TRACE_LEVEL_INFO,
1245 "LL_STATS_PEER_ALL : numPeers %u",
1246 pWifiPeerStat->numPeers);
1247 {
1248 for (i = 0; i < pWifiPeerStat->numPeers; i++)
1249 {
1250 pWifiPeerInfo = (tpSirWifiPeerInfo)
1251 ((uint8 *)pWifiPeerStat->peerInfo +
1252 ( i * sizeof(tSirWifiPeerInfo)));
1253
Dasari Srinivas1be0c4e2014-10-19 13:03:41 +05301254 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) {
1255 pWifiPeerInfo->type = WIFI_PEER_AP;
1256 }
1257 if (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) {
1258 pWifiPeerInfo->type = WIFI_PEER_P2P_GO;
1259 }
1260
Sunil Duttc69bccb2014-05-26 21:30:20 +05301261 hddLog(VOS_TRACE_LEVEL_INFO,
1262 " %d) LL_STATS Channel Stats "
1263 " Peer Type %u "
1264 " peerMacAddress %pM "
1265 " capabilities 0x%x "
1266 " numRate %u ",
1267 i,
1268 pWifiPeerInfo->type,
1269 pWifiPeerInfo->peerMacAddress,
1270 pWifiPeerInfo->capabilities,
1271 pWifiPeerInfo->numRate);
1272 {
1273 int j;
1274 for (j = 0; j < pWifiPeerInfo->numRate; j++)
1275 {
1276 pWifiRateStat = (tpSirWifiRateStat)
1277 ((tANI_U8 *) pWifiPeerInfo->rateStats +
1278 ( j * sizeof(tSirWifiRateStat)));
1279
1280 hddLog(VOS_TRACE_LEVEL_INFO,
1281 " peer Rate Stats "
1282 " preamble %u "
1283 " nss %u "
1284 " bw %u "
1285 " rateMcsIdx %u "
1286 " reserved %u "
1287 " bitrate %u "
1288 " txMpdu %u "
1289 " rxMpdu %u "
1290 " mpduLost %u "
1291 " retries %u "
1292 " retriesShort %u "
1293 " retriesLong %u",
1294 pWifiRateStat->rate.preamble,
1295 pWifiRateStat->rate.nss,
1296 pWifiRateStat->rate.bw,
1297 pWifiRateStat->rate.rateMcsIdx,
1298 pWifiRateStat->rate.reserved,
1299 pWifiRateStat->rate.bitrate,
1300 pWifiRateStat->txMpdu,
1301 pWifiRateStat->rxMpdu,
1302 pWifiRateStat->mpduLost,
1303 pWifiRateStat->retries,
1304 pWifiRateStat->retriesShort,
1305 pWifiRateStat->retriesLong);
1306 }
1307 }
1308 }
1309 }
1310
1311 /*
1312 * Allocate a size of 4096 for the peer stats comprising
1313 * each of size = sizeof (tSirWifiPeerInfo) + numRate *
1314 * sizeof (tSirWifiRateStat).Each field is put with an
1315 * NL attribute.The size of 4096 is considered assuming
1316 * that number of rates shall not exceed beyond 50 with
1317 * the sizeof (tSirWifiRateStat) being 32.
1318 */
1319 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05301320#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
1321 NULL,
1322#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301323 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1324 QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX,
1325 GFP_KERNEL);
1326 if (!vendor_event)
1327 {
1328 hddLog(VOS_TRACE_LEVEL_ERROR,
1329 "%s: cfg80211_vendor_event_alloc failed",
1330 __func__);
1331 return;
1332 }
1333 if (nla_put_u32(vendor_event,
1334 QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS,
1335 pWifiPeerStat->numPeers))
1336 {
1337 hddLog(VOS_TRACE_LEVEL_ERROR,
1338 "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__);
1339 kfree_skb(vendor_event);
1340 return;
1341 }
1342
1343 peerInfo = nla_nest_start(vendor_event,
1344 QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301345 if(!peerInfo)
1346 {
1347 hddLog(VOS_TRACE_LEVEL_ERROR,
1348 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO put fail",
1349 __func__);
1350 kfree_skb(vendor_event);
1351 return;
1352 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301353
1354 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1355 pWifiPeerStat->peerInfo);
1356
1357 for (i = 1; i <= pWifiPeerStat->numPeers; i++)
1358 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301359 int numRate = pWifiPeerInfo->numRate;
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301360 struct nlattr *peers = nla_nest_start(vendor_event, i);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301361
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301362 if(!peers)
1363 {
1364 hddLog(VOS_TRACE_LEVEL_ERROR,
1365 "%s: peer stats put fail",
1366 __func__);
1367 kfree_skb(vendor_event);
1368 return;
1369 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301370 if (FALSE == put_wifi_peer_info(
1371 pWifiPeerInfo, vendor_event))
1372 {
1373 hddLog(VOS_TRACE_LEVEL_ERROR,
1374 "%s: put_wifi_peer_info put fail", __func__);
1375 kfree_skb(vendor_event);
1376 return;
1377 }
1378
1379 pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *)
1380 pWifiPeerStat->peerInfo +
1381 (i * sizeof(tSirWifiPeerInfo)) +
1382 (numRate * sizeof (tSirWifiRateStat)));
1383 nla_nest_end(vendor_event, peers);
1384 }
1385 nla_nest_end(vendor_event, peerInfo);
1386 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301387
1388 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301389}
1390
1391/*
1392 * hdd_link_layer_process_iface_stats () - This function is called after
1393 * receiving Link Layer Interface statistics from FW.This function converts
1394 * the firmware data to the NL data and sends the same to the kernel/upper
1395 * layers.
1396 */
1397static v_VOID_t hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter,
1398 v_VOID_t *pData)
1399{
1400 tpSirWifiIfaceStat pWifiIfaceStat;
1401 struct sk_buff *vendor_event;
1402 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1403 int status;
1404
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301405 ENTER();
1406
Sunil Duttc69bccb2014-05-26 21:30:20 +05301407 status = wlan_hdd_validate_context(pHddCtx);
1408 if (0 != status)
1409 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301410 return;
1411 }
1412 /*
1413 * Allocate a size of 4096 for the interface stats comprising
1414 * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered
1415 * assuming that all these fit with in the limit.Please take
1416 * a call on the limit based on the data requirements on
1417 * interface statistics.
1418 */
1419 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05301420#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
1421 NULL,
1422#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301423 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
1424 QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX,
1425 GFP_KERNEL);
1426 if (!vendor_event)
1427 {
1428 hddLog(VOS_TRACE_LEVEL_ERROR,
1429 FL("cfg80211_vendor_event_alloc failed") );
1430 return;
1431 }
1432
1433 pWifiIfaceStat = (tpSirWifiIfaceStat) pData;
1434
Dino Mycle3b9536d2014-07-09 22:05:24 +05301435
1436 if (FALSE == hdd_get_interface_info( pAdapter,
1437 &pWifiIfaceStat->info))
1438 {
1439 hddLog(VOS_TRACE_LEVEL_ERROR,
1440 FL("hdd_get_interface_info get fail") );
1441 kfree_skb(vendor_event);
1442 return;
1443 }
1444
1445 if (FALSE == put_wifi_iface_stats( pAdapter, pWifiIfaceStat,
1446 vendor_event))
1447 {
1448 hddLog(VOS_TRACE_LEVEL_ERROR,
1449 FL("put_wifi_iface_stats fail") );
1450 kfree_skb(vendor_event);
1451 return;
1452 }
1453
Sunil Duttc69bccb2014-05-26 21:30:20 +05301454 hddLog(VOS_TRACE_LEVEL_INFO,
1455 "WMI_LINK_STATS_IFACE Data");
1456
1457 hddLog(VOS_TRACE_LEVEL_INFO,
1458 "LL_STATS_IFACE: "
1459 " Mode %u "
1460 " MAC %pM "
1461 " State %u "
1462 " Roaming %u "
1463 " capabilities 0x%x "
1464 " SSID %s "
1465 " BSSID %pM",
1466 pWifiIfaceStat->info.mode,
1467 pWifiIfaceStat->info.macAddr,
1468 pWifiIfaceStat->info.state,
1469 pWifiIfaceStat->info.roaming,
1470 pWifiIfaceStat->info.capabilities,
1471 pWifiIfaceStat->info.ssid,
1472 pWifiIfaceStat->info.bssid);
1473
1474 hddLog(VOS_TRACE_LEVEL_INFO,
1475 " AP country str: %c%c%c",
1476 pWifiIfaceStat->info.apCountryStr[0],
1477 pWifiIfaceStat->info.apCountryStr[1],
1478 pWifiIfaceStat->info.apCountryStr[2]);
1479
1480
1481 hddLog(VOS_TRACE_LEVEL_INFO,
1482 " Country Str Association: %c%c%c",
1483 pWifiIfaceStat->info.countryStr[0],
1484 pWifiIfaceStat->info.countryStr[1],
1485 pWifiIfaceStat->info.countryStr[2]);
1486
1487 hddLog(VOS_TRACE_LEVEL_INFO,
1488 " beaconRx %u "
1489 " mgmtRx %u "
1490 " mgmtActionRx %u "
1491 " mgmtActionTx %u "
Dino Mycle3b9536d2014-07-09 22:05:24 +05301492 " rssiMgmt %d "
1493 " rssiData %d "
1494 " rssiAck %d",
Sunil Duttc69bccb2014-05-26 21:30:20 +05301495 pWifiIfaceStat->beaconRx,
1496 pWifiIfaceStat->mgmtRx,
1497 pWifiIfaceStat->mgmtActionRx,
1498 pWifiIfaceStat->mgmtActionTx,
1499 pWifiIfaceStat->rssiMgmt,
1500 pWifiIfaceStat->rssiData,
1501 pWifiIfaceStat->rssiAck );
1502
1503
1504 {
1505 int i;
1506 for (i = 0 ; i < WIFI_AC_MAX; i ++)
1507 {
1508 hddLog(VOS_TRACE_LEVEL_INFO,
1509
1510 " %d) LL_STATS IFACE: "
1511 " ac: %u txMpdu: %u "
1512 " rxMpdu: %u txMcast: %u "
1513 " rxMcast: %u rxAmpdu: %u "
1514 " txAmpdu: %u mpduLost: %u "
1515 " retries: %u retriesShort: %u "
1516 " retriesLong: %u contentionTimeMin: %u "
1517 " contentionTimeMax: %u contentionTimeAvg: %u "
1518 " contentionNumSamples: %u",
1519 i,
1520 pWifiIfaceStat->AccessclassStats[i].ac,
1521 pWifiIfaceStat->AccessclassStats[i].txMpdu,
1522 pWifiIfaceStat->AccessclassStats[i].rxMpdu,
1523 pWifiIfaceStat->AccessclassStats[i].txMcast,
1524 pWifiIfaceStat->AccessclassStats[i].rxMcast,
1525 pWifiIfaceStat->AccessclassStats[i].rxAmpdu,
1526 pWifiIfaceStat->AccessclassStats[i].txAmpdu,
1527 pWifiIfaceStat->AccessclassStats[i].mpduLost,
1528 pWifiIfaceStat->AccessclassStats[i].retries,
1529 pWifiIfaceStat->
1530 AccessclassStats[i].retriesShort,
1531 pWifiIfaceStat->AccessclassStats[i].retriesLong,
1532 pWifiIfaceStat->
1533 AccessclassStats[i].contentionTimeMin,
1534 pWifiIfaceStat->
1535 AccessclassStats[i].contentionTimeMax,
1536 pWifiIfaceStat->
1537 AccessclassStats[i].contentionTimeAvg,
1538 pWifiIfaceStat->
1539 AccessclassStats[i].contentionNumSamples);
1540
1541 }
1542 }
1543
Sunil Duttc69bccb2014-05-26 21:30:20 +05301544 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301545
1546 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301547}
1548
1549/*
1550 * hdd_link_layer_process_radio_stats () - This function is called after
1551 * receiving Link Layer Radio statistics from FW.This function converts
1552 * the firmware data to the NL data and sends the same to the kernel/upper
1553 * layers.
1554 */
1555static v_VOID_t hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter,
1556 v_VOID_t *pData)
1557{
1558 int status, i;
1559 tpSirWifiRadioStat pWifiRadioStat;
1560 tpSirWifiChannelStats pWifiChannelStats;
1561 struct sk_buff *vendor_event;
1562 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
1563 struct nlattr *chList;
1564
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301565 ENTER();
1566
Sunil Duttc69bccb2014-05-26 21:30:20 +05301567 status = wlan_hdd_validate_context(pHddCtx);
1568 if (0 != status)
1569 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301570 return;
1571 }
1572 pWifiRadioStat = (tpSirWifiRadioStat) pData;
1573
1574 hddLog(VOS_TRACE_LEVEL_INFO,
1575 "LL_STATS_RADIO"
1576 " radio is %d onTime is %u "
1577 " txTime is %u rxTime is %u "
1578 " onTimeScan is %u onTimeNbd is %u "
Dino Mycle6fb96c12014-06-10 11:52:40 +05301579 " onTimeEXTScan is %u onTimeRoamScan is %u "
Sunil Duttc69bccb2014-05-26 21:30:20 +05301580 " onTimePnoScan is %u onTimeHs20 is %u "
1581 " numChannels is %u",
1582 pWifiRadioStat->radio, pWifiRadioStat->onTime,
1583 pWifiRadioStat->txTime, pWifiRadioStat->rxTime,
1584 pWifiRadioStat->onTimeScan, pWifiRadioStat->onTimeNbd,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301585 pWifiRadioStat->onTimeEXTScan,
Sunil Duttc69bccb2014-05-26 21:30:20 +05301586 pWifiRadioStat->onTimeRoamScan,
1587 pWifiRadioStat->onTimePnoScan,
1588 pWifiRadioStat->onTimeHs20,
1589 pWifiRadioStat->numChannels);
1590 /*
1591 * Allocate a size of 4096 for the Radio stats comprising
1592 * sizeof (tSirWifiRadioStat) + numChannels * sizeof
1593 * (tSirWifiChannelStats).Each channel data is put with an
1594 * NL attribute.The size of 4096 is considered assuming that
1595 * number of channels shall not exceed beyond 60 with the
1596 * sizeof (tSirWifiChannelStats) being 24 bytes.
1597 */
1598
1599 vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05301600#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
1601 NULL,
1602#endif
Sunil Duttc69bccb2014-05-26 21:30:20 +05301603 LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN ,
1604 QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX,
1605 GFP_KERNEL);
1606
1607 if (!vendor_event)
1608 {
1609 hddLog(VOS_TRACE_LEVEL_ERROR,
1610 FL("cfg80211_vendor_event_alloc failed") );
1611 return;
1612 }
1613
1614 if (nla_put_u32(vendor_event,
1615 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID,
1616 pWifiRadioStat->radio) ||
1617 nla_put_u32(vendor_event,
1618 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME,
1619 pWifiRadioStat->onTime) ||
1620 nla_put_u32(vendor_event,
1621 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME,
1622 pWifiRadioStat->txTime) ||
1623 nla_put_u32(vendor_event,
1624 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME,
1625 pWifiRadioStat->rxTime) ||
1626 nla_put_u32(vendor_event,
1627 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN,
1628 pWifiRadioStat->onTimeScan) ||
1629 nla_put_u32(vendor_event,
1630 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD,
1631 pWifiRadioStat->onTimeNbd) ||
1632 nla_put_u32(vendor_event,
Dino Mycle6fb96c12014-06-10 11:52:40 +05301633 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_EXTSCAN,
1634 pWifiRadioStat->onTimeEXTScan)||
Sunil Duttc69bccb2014-05-26 21:30:20 +05301635 nla_put_u32(vendor_event,
1636 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN,
1637 pWifiRadioStat->onTimeRoamScan) ||
1638 nla_put_u32(vendor_event,
1639 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN,
1640 pWifiRadioStat->onTimePnoScan) ||
1641 nla_put_u32(vendor_event,
1642 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20,
1643 pWifiRadioStat->onTimeHs20) ||
1644 nla_put_u32(vendor_event,
1645 QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS,
1646 pWifiRadioStat->numChannels))
1647 {
1648 hddLog(VOS_TRACE_LEVEL_ERROR,
1649 FL("QCA_WLAN_VENDOR_ATTR put fail"));
1650 kfree_skb(vendor_event);
1651 return ;
1652 }
1653
1654 chList = nla_nest_start(vendor_event,
1655 QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301656 if(!chList)
1657 {
1658 hddLog(VOS_TRACE_LEVEL_ERROR,
1659 "%s: QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO put fail",
1660 __func__);
1661 kfree_skb(vendor_event);
1662 return;
1663 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301664 for (i = 0; i < pWifiRadioStat->numChannels; i++)
1665 {
1666 struct nlattr *chInfo;
1667
1668 pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*)
1669 pWifiRadioStat->channels +
1670 (i * sizeof(tSirWifiChannelStats)));
1671
1672 hddLog(VOS_TRACE_LEVEL_INFO,
1673 " %d) Channel Info"
1674 " width is %u "
1675 " CenterFreq %u "
1676 " CenterFreq0 %u "
1677 " CenterFreq1 %u "
1678 " onTime %u "
1679 " ccaBusyTime %u",
1680 i,
1681 pWifiChannelStats->channel.width,
1682 pWifiChannelStats->channel.centerFreq,
1683 pWifiChannelStats->channel.centerFreq0,
1684 pWifiChannelStats->channel.centerFreq1,
1685 pWifiChannelStats->onTime,
1686 pWifiChannelStats->ccaBusyTime);
1687
1688
1689 chInfo = nla_nest_start(vendor_event, i);
Sushant Kaushikee1f55e2015-01-22 11:27:01 +05301690 if(!chInfo)
1691 {
1692 hddLog(VOS_TRACE_LEVEL_ERROR,
1693 "%s: failed to put chInfo",
1694 __func__);
1695 kfree_skb(vendor_event);
1696 return;
1697 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301698
1699 if (nla_put_u32(vendor_event,
1700 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH,
1701 pWifiChannelStats->channel.width) ||
1702 nla_put_u32(vendor_event,
1703 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ,
1704 pWifiChannelStats->channel.centerFreq) ||
1705 nla_put_u32(vendor_event,
1706 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0,
1707 pWifiChannelStats->channel.centerFreq0) ||
1708 nla_put_u32(vendor_event,
1709 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1,
1710 pWifiChannelStats->channel.centerFreq1) ||
1711 nla_put_u32(vendor_event,
1712 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME,
1713 pWifiChannelStats->onTime) ||
1714 nla_put_u32(vendor_event,
1715 QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME,
1716 pWifiChannelStats->ccaBusyTime))
1717 {
1718 hddLog(VOS_TRACE_LEVEL_ERROR,
1719 FL("cfg80211_vendor_event_alloc failed") );
1720 kfree_skb(vendor_event);
1721 return ;
1722 }
1723 nla_nest_end(vendor_event, chInfo);
1724 }
1725 nla_nest_end(vendor_event, chList);
1726
1727 cfg80211_vendor_event(vendor_event, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301728
1729 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301730 return;
1731}
1732
1733/*
1734 * hdd_link_layer_stats_ind_callback () - This function is called after
1735 * receiving Link Layer indications from FW.This callback converts the firmware
1736 * data to the NL data and send the same to the kernel/upper layers.
1737 */
1738static void hdd_link_layer_stats_ind_callback ( void *pCtx,
1739 int indType,
Dino Mycled3d50022014-07-07 12:58:25 +05301740 void *pRsp, u8 *macAddr)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301741{
Dino Mycled3d50022014-07-07 12:58:25 +05301742 hdd_context_t *pHddCtx = (hdd_context_t *)pCtx;
1743 hdd_adapter_t *pAdapter = NULL;
1744 tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301745 int status;
1746
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301747 ENTER();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301748
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301749 status = wlan_hdd_validate_context(pHddCtx);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301750 if (0 != status)
1751 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301752 return;
1753 }
1754
Dino Mycled3d50022014-07-07 12:58:25 +05301755 pAdapter = hdd_get_adapter_by_macaddr(pHddCtx, macAddr);
1756 if (NULL == pAdapter)
1757 {
1758 hddLog(VOS_TRACE_LEVEL_ERROR,
1759 FL(" MAC address %pM does not exist with host"),
1760 macAddr);
1761 return;
1762 }
1763
Sunil Duttc69bccb2014-05-26 21:30:20 +05301764 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301765 "%s: Interface: %s LLStats indType: %d", __func__,
1766 pAdapter->dev->name, indType);
1767
Sunil Duttc69bccb2014-05-26 21:30:20 +05301768 switch (indType)
1769 {
1770 case SIR_HAL_LL_STATS_RESULTS_RSP:
1771 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301772 hddLog(VOS_TRACE_LEVEL_INFO,
1773 FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP") );
1774 hddLog(VOS_TRACE_LEVEL_INFO,
1775 "LL_STATS RESULTS RESPONSE paramID = 0x%x",
1776 linkLayerStatsResults->paramId);
1777 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301778 "LL_STATS RESULTS RESPONSE ifaceId = %u MAC: %pM",
1779 linkLayerStatsResults->ifaceId, macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301780 hddLog(VOS_TRACE_LEVEL_INFO,
1781 "LL_STATS RESULTS RESPONSE respId = %u",
1782 linkLayerStatsResults->respId);
1783 hddLog(VOS_TRACE_LEVEL_INFO,
1784 "LL_STATS RESULTS RESPONSE moreResultToFollow = %u",
1785 linkLayerStatsResults->moreResultToFollow);
1786 hddLog(VOS_TRACE_LEVEL_INFO,
1787 "LL_STATS RESULTS RESPONSE result = %p",
1788 linkLayerStatsResults->result);
1789 if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO )
1790 {
1791 hdd_link_layer_process_radio_stats(pAdapter,
1792 (v_VOID_t *)linkLayerStatsResults->result);
1793 }
1794 else if ( linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE )
1795 {
1796 hdd_link_layer_process_iface_stats(pAdapter,
1797 (v_VOID_t *)linkLayerStatsResults->result);
1798 }
1799 else if ( linkLayerStatsResults->paramId &
1800 WMI_LINK_STATS_ALL_PEER )
1801 {
1802 hdd_link_layer_process_peer_stats(pAdapter,
1803 (v_VOID_t *)linkLayerStatsResults->result);
1804 } /* WMI_LINK_STATS_ALL_PEER */
1805 else
1806 {
1807 hddLog(VOS_TRACE_LEVEL_ERROR,
1808 FL("INVALID LL_STATS_NOTIFY RESPONSE ***********"));
1809 }
1810
1811 break;
1812 }
1813 default:
1814 hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType);
1815 break;
1816 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301817
1818 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301819 return;
1820}
1821
1822const struct
1823nla_policy
1824qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] =
1825{
1826 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] =
1827 { .type = NLA_U32 },
1828 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] =
1829 { .type = NLA_U32 },
1830};
1831
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301832static int __wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1833 struct wireless_dev *wdev,
1834 const void *data,
1835 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301836{
1837 int status;
1838 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301839 tSirLLStatsSetReq linkLayerStatsSetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301840 struct net_device *dev = wdev->netdev;
1841 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
1842 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Srinivas Dasari98947432014-11-07 19:41:24 +05301843 hdd_station_ctx_t *pHddStaCtx;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301844
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301845 ENTER();
1846
Sunil Duttc69bccb2014-05-26 21:30:20 +05301847 status = wlan_hdd_validate_context(pHddCtx);
1848 if (0 != status)
1849 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301850 return -EINVAL;
1851 }
1852
1853 if (NULL == pAdapter)
1854 {
1855 hddLog(VOS_TRACE_LEVEL_ERROR,
1856 FL("HDD adapter is Null"));
1857 return -ENODEV;
1858 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05301859 /* check the LLStats Capability */
1860 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
1861 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
1862 {
1863 hddLog(VOS_TRACE_LEVEL_ERROR,
1864 FL("Link Layer Statistics not supported by Firmware"));
1865 return -EINVAL;
1866 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301867
1868 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX,
1869 (struct nlattr *)data,
1870 data_len, qca_wlan_vendor_ll_set_policy))
1871 {
1872 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
1873 return -EINVAL;
1874 }
1875 if (!tb_vendor
1876 [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD])
1877 {
1878 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present"));
1879 return -EINVAL;
1880 }
1881 if (!tb_vendor[
1882 QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING])
1883 {
1884 hddLog(VOS_TRACE_LEVEL_ERROR, FL(" Stats Gathering Not Present"));
1885 return -EINVAL;
1886 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05301887 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05301888 linkLayerStatsSetReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301889
Dino Mycledf0a5d92014-07-04 09:41:55 +05301890 linkLayerStatsSetReq.mpduSizeThreshold =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301891 nla_get_u32(
1892 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]);
1893
Dino Mycledf0a5d92014-07-04 09:41:55 +05301894 linkLayerStatsSetReq.aggressiveStatisticsGathering =
Sunil Duttc69bccb2014-05-26 21:30:20 +05301895 nla_get_u32(
1896 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]);
1897
Dino Mycled3d50022014-07-07 12:58:25 +05301898 vos_mem_copy(linkLayerStatsSetReq.macAddr,
1899 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05301900
1901
1902 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301903 "LL_STATS_SET reqId = %d", linkLayerStatsSetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301904 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05301905 "LL_STATS_SET MAC = %pM", linkLayerStatsSetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301906 hddLog(VOS_TRACE_LEVEL_INFO,
1907 "LL_STATS_SET mpduSizeThreshold = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301908 linkLayerStatsSetReq.mpduSizeThreshold);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301909 hddLog(VOS_TRACE_LEVEL_INFO,
1910 "LL_STATS_SET aggressive Statistics Gathering = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05301911 linkLayerStatsSetReq.aggressiveStatisticsGathering);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301912
1913 if (eHAL_STATUS_SUCCESS != sme_SetLinkLayerStatsIndCB(
1914 pHddCtx->hHal,
Dino Mycled3d50022014-07-07 12:58:25 +05301915 hdd_link_layer_stats_ind_callback))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301916 {
1917 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1918 "sme_SetLinkLayerStatsIndCB Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301919 return -EINVAL;
1920
1921 }
Srinivas Dasari98947432014-11-07 19:41:24 +05301922
1923 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
1924 if (VOS_STATUS_SUCCESS !=
1925 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
1926 pHddStaCtx->conn_info.staId[0], WIFI_STATS_IFACE))
1927 {
1928 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1929 "WLANTL_ClearInterfaceStats Failed", __func__);
1930 return -EINVAL;
1931 }
1932
Sunil Duttc69bccb2014-05-26 21:30:20 +05301933 if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05301934 &linkLayerStatsSetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05301935 {
1936 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
1937 "sme_LLStatsSetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301938 return -EINVAL;
1939 }
1940
1941 pAdapter->isLinkLayerStatsSet = 1;
1942
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301943 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05301944 return 0;
1945}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301946static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy,
1947 struct wireless_dev *wdev,
1948 const void *data,
1949 int data_len)
1950{
1951 int ret = 0;
1952
1953 vos_ssr_protect(__func__);
1954 ret = __wlan_hdd_cfg80211_ll_stats_set(wiphy, wdev, data, data_len);
1955 vos_ssr_unprotect(__func__);
1956
1957 return ret;
1958}
Sunil Duttc69bccb2014-05-26 21:30:20 +05301959
1960const struct
1961nla_policy
1962qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] =
1963{
1964 /* Unsigned 32bit value provided by the caller issuing the GET stats
1965 * command. When reporting
1966 * the stats results, the driver uses the same value to indicate
1967 * which GET request the results
1968 * correspond to.
1969 */
1970 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 },
1971
1972 /* Unsigned 32bit value . bit mask to identify what statistics are
1973 requested for retrieval */
1974 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 },
1975};
1976
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05301977static int __wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
1978 struct wireless_dev *wdev,
1979 const void *data,
1980 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05301981{
1982 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
1983 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05301984 tSirLLStatsGetReq linkLayerStatsGetReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05301985 struct net_device *dev = wdev->netdev;
1986 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Mukul Sharma10313ba2015-07-29 19:14:39 +05301987 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Sunil Duttc69bccb2014-05-26 21:30:20 +05301988 int status;
1989
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05301990 ENTER();
1991
Sunil Duttc69bccb2014-05-26 21:30:20 +05301992 status = wlan_hdd_validate_context(pHddCtx);
1993 if (0 != status)
1994 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05301995 return -EINVAL ;
1996 }
1997
1998 if (NULL == pAdapter)
1999 {
2000 hddLog(VOS_TRACE_LEVEL_FATAL,
2001 "%s: HDD adapter is Null", __func__);
2002 return -ENODEV;
2003 }
Mukul Sharma10313ba2015-07-29 19:14:39 +05302004
2005 if (pHddStaCtx == NULL)
2006 {
2007 hddLog(VOS_TRACE_LEVEL_FATAL,
2008 "%s: HddStaCtx is Null", __func__);
2009 return -ENODEV;
2010 }
2011
Dino Mycledf0a5d92014-07-04 09:41:55 +05302012 /* check the LLStats Capability */
2013 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2014 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2015 {
2016 hddLog(VOS_TRACE_LEVEL_ERROR,
2017 FL("Link Layer Statistics not supported by Firmware"));
2018 return -EINVAL;
2019 }
2020
Sunil Duttc69bccb2014-05-26 21:30:20 +05302021
2022 if (!pAdapter->isLinkLayerStatsSet)
2023 {
2024 hddLog(VOS_TRACE_LEVEL_FATAL,
2025 "%s: isLinkLayerStatsSet : %d",
2026 __func__, pAdapter->isLinkLayerStatsSet);
2027 return -EINVAL;
2028 }
2029
Mukul Sharma10313ba2015-07-29 19:14:39 +05302030 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
2031 {
2032 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
2033 "%s: Roaming in progress, so unable to proceed this request", __func__);
2034 return -EBUSY;
2035 }
2036
Sunil Duttc69bccb2014-05-26 21:30:20 +05302037 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX,
2038 (struct nlattr *)data,
2039 data_len, qca_wlan_vendor_ll_get_policy))
2040 {
2041 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2042 return -EINVAL;
2043 }
2044
2045 if (!tb_vendor
2046 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID])
2047 {
2048 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present"));
2049 return -EINVAL;
2050 }
2051
2052 if (!tb_vendor
2053 [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK])
2054 {
2055 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present"));
2056 return -EINVAL;
2057 }
2058
Sunil Duttc69bccb2014-05-26 21:30:20 +05302059
Dino Mycledf0a5d92014-07-04 09:41:55 +05302060 linkLayerStatsGetReq.reqId =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302061 nla_get_u32( tb_vendor[
2062 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]);
Dino Mycledf0a5d92014-07-04 09:41:55 +05302063 linkLayerStatsGetReq.paramIdMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302064 nla_get_u32( tb_vendor[
2065 QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]);
2066
Dino Mycled3d50022014-07-07 12:58:25 +05302067 vos_mem_copy(linkLayerStatsGetReq.macAddr,
2068 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302069
2070 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302071 "LL_STATS_GET reqId = %d", linkLayerStatsGetReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302072 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302073 "LL_STATS_GET MAC = %pM", linkLayerStatsGetReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302074 hddLog(VOS_TRACE_LEVEL_INFO,
2075 "LL_STATS_GET paramIdMask = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302076 linkLayerStatsGetReq.paramIdMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302077
2078 if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq( pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302079 &linkLayerStatsGetReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302080 {
2081 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2082 "sme_LLStatsGetReq Failed", __func__);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302083 return -EINVAL;
2084 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302085
2086 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302087 return 0;
2088}
2089
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302090static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy,
2091 struct wireless_dev *wdev,
2092 const void *data,
2093 int data_len)
2094{
2095 int ret = 0;
2096
2097 vos_ssr_protect(__func__);
2098 ret = __wlan_hdd_cfg80211_ll_stats_get(wiphy, wdev, data, data_len);
2099 vos_ssr_unprotect(__func__);
2100
2101 return ret;
2102}
2103
Sunil Duttc69bccb2014-05-26 21:30:20 +05302104const struct
2105nla_policy
2106qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] =
2107{
2108 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 },
2109 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 },
2110 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 },
2111 [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 },
2112};
2113
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302114static int __wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2115 struct wireless_dev *wdev,
2116 const void *data,
2117 int data_len)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302118{
2119 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
2120 struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1];
Dino Mycledf0a5d92014-07-04 09:41:55 +05302121 tSirLLStatsClearReq linkLayerStatsClearReq;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302122 struct net_device *dev = wdev->netdev;
2123 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
2124 u32 statsClearReqMask;
2125 u8 stopReq;
2126 int status;
2127
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302128 ENTER();
2129
Sunil Duttc69bccb2014-05-26 21:30:20 +05302130 status = wlan_hdd_validate_context(pHddCtx);
2131 if (0 != status)
2132 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05302133 return -EINVAL;
2134 }
2135
2136 if (NULL == pAdapter)
2137 {
2138 hddLog(VOS_TRACE_LEVEL_FATAL,
2139 "%s: HDD adapter is Null", __func__);
2140 return -ENODEV;
2141 }
Dino Mycledf0a5d92014-07-04 09:41:55 +05302142 /* check the LLStats Capability */
2143 if ( (TRUE != pHddCtx->cfg_ini->fEnableLLStats) ||
2144 (TRUE != sme_IsFeatureSupportedByFW(LINK_LAYER_STATS_MEAS)))
2145 {
2146 hddLog(VOS_TRACE_LEVEL_ERROR,
2147 FL("Enable LLStats Capability"));
2148 return -EINVAL;
2149 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05302150
2151 if (!pAdapter->isLinkLayerStatsSet)
2152 {
2153 hddLog(VOS_TRACE_LEVEL_FATAL,
2154 "%s: isLinkLayerStatsSet : %d",
2155 __func__, pAdapter->isLinkLayerStatsSet);
2156 return -EINVAL;
2157 }
2158
2159 if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX,
2160 (struct nlattr *)data,
2161 data_len, qca_wlan_vendor_ll_clr_policy))
2162 {
2163 hddLog(VOS_TRACE_LEVEL_ERROR, FL() );
2164 return -EINVAL;
2165 }
2166
2167 if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] ||
2168
2169 !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ])
2170 {
2171 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA") );
2172 return -EINVAL;
2173
2174 }
2175
Sunil Duttc69bccb2014-05-26 21:30:20 +05302176
Dino Mycledf0a5d92014-07-04 09:41:55 +05302177 statsClearReqMask = linkLayerStatsClearReq.statsClearReqMask =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302178 nla_get_u32(
2179 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]);
2180
Dino Mycledf0a5d92014-07-04 09:41:55 +05302181 stopReq = linkLayerStatsClearReq.stopReq =
Sunil Duttc69bccb2014-05-26 21:30:20 +05302182 nla_get_u8(
2183 tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]);
2184
2185 // Shall take the request Id if the Upper layers pass. 1 For now.
Dino Mycledf0a5d92014-07-04 09:41:55 +05302186 linkLayerStatsClearReq.reqId = 1;
Sunil Duttc69bccb2014-05-26 21:30:20 +05302187
Dino Mycled3d50022014-07-07 12:58:25 +05302188 vos_mem_copy(linkLayerStatsClearReq.macAddr,
2189 pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Sunil Duttc69bccb2014-05-26 21:30:20 +05302190
2191 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302192 "LL_STATS_CLEAR reqId = %d", linkLayerStatsClearReq.reqId);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302193 hddLog(VOS_TRACE_LEVEL_INFO,
Dino Mycled3d50022014-07-07 12:58:25 +05302194 "LL_STATS_CLEAR MAC = %pM", linkLayerStatsClearReq.macAddr);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302195 hddLog(VOS_TRACE_LEVEL_INFO,
2196 "LL_STATS_CLEAR statsClearReqMask = 0x%X",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302197 linkLayerStatsClearReq.statsClearReqMask);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302198 hddLog(VOS_TRACE_LEVEL_INFO,
2199 "LL_STATS_CLEAR stopReq = %d",
Dino Mycledf0a5d92014-07-04 09:41:55 +05302200 linkLayerStatsClearReq.stopReq);
Sunil Duttc69bccb2014-05-26 21:30:20 +05302201
2202 if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302203 &linkLayerStatsClearReq))
Sunil Duttc69bccb2014-05-26 21:30:20 +05302204 {
2205 struct sk_buff *temp_skbuff;
Srinivas Dasari98947432014-11-07 19:41:24 +05302206 hdd_station_ctx_t *pHddStaCtx;
2207
2208 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
2209 if (VOS_STATUS_SUCCESS !=
2210 WLANTL_ClearInterfaceStats((WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
2211 pHddStaCtx->conn_info.staId[0], statsClearReqMask))
2212 {
2213 hddLog(VOS_TRACE_LEVEL_ERROR, "%s:"
2214 "WLANTL_ClearInterfaceStats Failed", __func__);
2215 return -EINVAL;
2216 }
2217 if ((statsClearReqMask & WIFI_STATS_IFACE_AC) ||
2218 (statsClearReqMask & WIFI_STATS_IFACE)) {
2219 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VO] = 0;
2220 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_VI] = 0;
2221 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BE] = 0;
2222 pAdapter->hdd_stats.hddTxRxStats.txMcast[WLANTL_AC_BK] = 0;
2223 }
2224
Sunil Duttc69bccb2014-05-26 21:30:20 +05302225 temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
2226 2 * sizeof(u32) +
2227 NLMSG_HDRLEN);
2228
2229 if (temp_skbuff != NULL)
2230 {
2231
2232 if (nla_put_u32(temp_skbuff,
2233 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK,
2234 statsClearReqMask) ||
2235 nla_put_u32(temp_skbuff,
2236 QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP,
2237 stopReq))
2238 {
2239 hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail"));
2240 kfree_skb(temp_skbuff);
2241 return -EINVAL;
2242 }
2243 /* If the ask is to stop the stats collection as part of clear
2244 * (stopReq = 1) , ensure that no further requests of get
2245 * go to the firmware by having isLinkLayerStatsSet set to 0.
2246 * However it the stopReq as part of the clear request is 0 ,
Dino Mycledf0a5d92014-07-04 09:41:55 +05302247 * the request to get the statistics are honoured as in this
Sunil Duttc69bccb2014-05-26 21:30:20 +05302248 * case the firmware is just asked to clear the statistics.
2249 */
Dino Mycledf0a5d92014-07-04 09:41:55 +05302250 if (linkLayerStatsClearReq.stopReq == 1)
Sunil Duttc69bccb2014-05-26 21:30:20 +05302251 pAdapter->isLinkLayerStatsSet = 0;
2252 return cfg80211_vendor_cmd_reply(temp_skbuff);
2253 }
2254 return -ENOMEM;
2255 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302256
2257 EXIT();
Sunil Duttc69bccb2014-05-26 21:30:20 +05302258 return -EINVAL;
2259}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05302260static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy,
2261 struct wireless_dev *wdev,
2262 const void *data,
2263 int data_len)
2264{
2265 int ret = 0;
2266
2267 vos_ssr_protect(__func__);
2268 ret = __wlan_hdd_cfg80211_ll_stats_clear(wiphy, wdev, data, data_len);
2269 vos_ssr_unprotect(__func__);
2270
2271 return ret;
2272
2273
2274}
Sunil Duttc69bccb2014-05-26 21:30:20 +05302275#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
2276
Dino Mycle6fb96c12014-06-10 11:52:40 +05302277#ifdef WLAN_FEATURE_EXTSCAN
2278static const struct nla_policy
2279wlan_hdd_extscan_config_policy
2280 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1] =
2281{
2282 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID] =
2283 { .type = NLA_U32 },
2284 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND] =
2285 { .type = NLA_U32 },
2286 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 },
2287 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME] =
2288 { .type = NLA_U32 },
2289 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE] = { .type = NLA_U8 },
2290 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CLASS] = { .type = NLA_U8 },
2291
2292 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX] = { .type = NLA_U8 },
2293 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND] = { .type = NLA_U8 },
2294 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD] = { .type = NLA_U32 },
2295 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS] =
2296 { .type = NLA_U8 },
2297 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS] =
2298 { .type = NLA_U32 },
2299 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD] =
2300 { .type = NLA_U32 },
2301 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN] =
2302 { .type = NLA_U32 },
2303 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD] =
2304 { .type = NLA_U8 },
2305 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS] =
2306 { .type = NLA_U8 },
2307 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH] =
2308 { .type = NLA_U8 },
2309
2310 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_MAX] =
2311 { .type = NLA_U32 },
2312 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID] =
2313 { .type = NLA_UNSPEC },
2314 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW] =
2315 { .type = NLA_S32 },
2316 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH] =
2317 { .type = NLA_S32 },
2318 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL] =
2319 { .type = NLA_U32 },
2320 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP] =
2321 { .type = NLA_U32 },
2322 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE] =
2323 { .type = NLA_U32 },
2324 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]
2325 = { .type = NLA_U32 },
2326 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] =
2327 { .type = NLA_U32 },
2328 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .type =
2329 NLA_U32 },
2330};
2331
2332static void wlan_hdd_cfg80211_extscan_get_capabilities_ind(void *ctx, void *pMsg)
2333{
2334 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2335 struct sk_buff *skb = NULL;
2336 tpSirEXTScanCapabilitiesEvent pData =
2337 (tpSirEXTScanCapabilitiesEvent) pMsg;
2338
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302339 ENTER();
2340
2341 if (wlan_hdd_validate_context(pHddCtx))
2342 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302343 return;
2344 }
2345
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302346 if (!pMsg)
2347 {
2348 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2349 return;
2350 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05302351 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302352#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2353 NULL,
2354#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302355 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2356 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX,
2357 GFP_KERNEL);
2358
2359 if (!skb) {
2360 hddLog(VOS_TRACE_LEVEL_ERROR,
2361 FL("cfg80211_vendor_event_alloc failed"));
2362 return;
2363 }
2364
2365 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2366 hddLog(VOS_TRACE_LEVEL_INFO, "Scan cache size (%u)", pData->scanCacheSize);
2367 hddLog(VOS_TRACE_LEVEL_INFO, "Scan buckets (%u)", pData->scanBuckets);
2368 hddLog(VOS_TRACE_LEVEL_INFO, "Max AP per scan (%u)", pData->maxApPerScan);
2369 hddLog(VOS_TRACE_LEVEL_INFO, "maxRssiSampleSize (%u)",
2370 pData->maxRssiSampleSize);
2371 hddLog(VOS_TRACE_LEVEL_INFO, "maxScanReportingThreshold (%u)",
2372 pData->maxScanReportingThreshold);
2373 hddLog(VOS_TRACE_LEVEL_INFO, "maxHotlistAPs (%u)", pData->maxHotlistAPs);
2374 hddLog(VOS_TRACE_LEVEL_INFO, "maxSignificantWifiChangeAPs (%u)",
2375 pData->maxSignificantWifiChangeAPs);
2376 hddLog(VOS_TRACE_LEVEL_INFO, "maxBsidHistoryEntries (%u)",
2377 pData->maxBsidHistoryEntries);
2378
2379 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2380 pData->requestId) ||
2381 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status) ||
2382 nla_put_u32(skb,
2383 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_CACHE_SIZE,
2384 pData->scanCacheSize) ||
2385 nla_put_u32(skb,
2386 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_BUCKETS,
2387 pData->scanBuckets) ||
2388 nla_put_u32(skb,
2389 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_AP_CACHE_PER_SCAN,
2390 pData->maxApPerScan) ||
2391 nla_put_u32(skb,
2392 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_RSSI_SAMPLE_SIZE,
2393 pData->maxRssiSampleSize) ||
2394 nla_put_u32(skb,
2395 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SCAN_REPORTING_THRESHOLD,
2396 pData->maxScanReportingThreshold) ||
2397 nla_put_u32(skb,
2398 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_HOTLIST_APS,
2399 pData->maxHotlistAPs) ||
2400 nla_put_u32(skb,
2401 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_SIGNIFICANT_WIFI_CHANGE_APS,
2402 pData->maxSignificantWifiChangeAPs) ||
2403 nla_put_u32(skb,
2404 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CAPABILITIES_MAX_BSSID_HISTORY_ENTRIES,
2405 pData->maxBsidHistoryEntries)) {
2406 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2407 goto nla_put_failure;
2408 }
2409
2410 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302411 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302412 return;
2413
2414nla_put_failure:
2415 kfree_skb(skb);
2416 return;
2417}
2418
2419
2420static void wlan_hdd_cfg80211_extscan_start_rsp(void *ctx, void *pMsg)
2421{
2422 tpSirEXTScanStartRspParams pData = (tpSirEXTScanStartRspParams) pMsg;
2423 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2424 struct sk_buff *skb = NULL;
2425 tpAniSirGlobal pMac = PMAC_STRUCT( pHddCtx->hHal );
2426
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302427 ENTER();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302428
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302429 if (wlan_hdd_validate_context(pHddCtx)){
2430 return;
2431 }
2432 if (!pMsg)
2433 {
2434 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302435 return;
2436 }
2437
2438 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302439#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2440 NULL,
2441#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302442 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2443 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX,
2444 GFP_KERNEL);
2445
2446 if (!skb) {
2447 hddLog(VOS_TRACE_LEVEL_ERROR,
2448 FL("cfg80211_vendor_event_alloc failed"));
2449 return;
2450 }
2451 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2452 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2453 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2454
2455 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2456 pData->requestId) ||
2457 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2458 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2459 goto nla_put_failure;
2460 }
2461
2462 /*
2463 * Store the Request ID for comparing with the requestID obtained
2464 * in other requests.HDD shall return a failure is the extscan_stop
2465 * request is issued with a different requestId as that of the
2466 * extscan_start request. Also, This requestId shall be used while
2467 * indicating the full scan results to the upper layers.
2468 * The requestId is stored with the assumption that the firmware
2469 * shall return the ext scan start request's requestId in ext scan
2470 * start response.
2471 */
2472 if (pData->status == 0)
2473 pMac->sme.extScanStartReqId = pData->requestId;
2474
2475
2476 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302477 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302478 return;
2479
2480nla_put_failure:
2481 kfree_skb(skb);
2482 return;
2483}
2484
2485
2486static void wlan_hdd_cfg80211_extscan_stop_rsp(void *ctx, void *pMsg)
2487{
2488 tpSirEXTScanStopRspParams pData = (tpSirEXTScanStopRspParams) pMsg;
2489 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2490 struct sk_buff *skb = NULL;
2491
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302492 ENTER();
2493
2494 if (wlan_hdd_validate_context(pHddCtx)){
2495 return;
2496 }
2497 if (!pMsg)
2498 {
2499 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302500 return;
2501 }
2502
2503 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302504#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2505 NULL,
2506#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302507 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2508 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX,
2509 GFP_KERNEL);
2510
2511 if (!skb) {
2512 hddLog(VOS_TRACE_LEVEL_ERROR,
2513 FL("cfg80211_vendor_event_alloc failed"));
2514 return;
2515 }
2516 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2517 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2518
2519 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2520 pData->requestId) ||
2521 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2522 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2523 goto nla_put_failure;
2524 }
2525
2526 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302527 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302528 return;
2529
2530nla_put_failure:
2531 kfree_skb(skb);
2532 return;
2533}
2534
2535
2536static void wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(void *ctx,
2537 void *pMsg)
2538{
2539 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2540 struct sk_buff *skb = NULL;
2541 tpSirEXTScanSetBssidHotListRspParams pData =
2542 (tpSirEXTScanSetBssidHotListRspParams) pMsg;
2543
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302544 ENTER();
2545
2546 if (wlan_hdd_validate_context(pHddCtx)){
Dino Mycle6fb96c12014-06-10 11:52:40 +05302547 return;
2548 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302549 if (!pMsg)
2550 {
2551 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2552 return;
2553 }
2554
Dino Mycle6fb96c12014-06-10 11:52:40 +05302555 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302556#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2557 NULL,
2558#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302559 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2560 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX,
2561 GFP_KERNEL);
2562
2563 if (!skb) {
2564 hddLog(VOS_TRACE_LEVEL_ERROR,
2565 FL("cfg80211_vendor_event_alloc failed"));
2566 return;
2567 }
2568 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2569 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2570 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2571
2572 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2573 pData->requestId) ||
2574 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2575 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2576 goto nla_put_failure;
2577 }
2578
2579 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302580 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302581 return;
2582
2583nla_put_failure:
2584 kfree_skb(skb);
2585 return;
2586}
2587
2588static void wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(void *ctx,
2589 void *pMsg)
2590{
2591 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2592 struct sk_buff *skb = NULL;
2593 tpSirEXTScanResetBssidHotlistRspParams pData =
2594 (tpSirEXTScanResetBssidHotlistRspParams) pMsg;
2595
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302596 ENTER();
2597
2598 if (wlan_hdd_validate_context(pHddCtx)) {
2599 return;
2600 }
2601 if (!pMsg)
2602 {
2603 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302604 return;
2605 }
2606
2607 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302608#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2609 NULL,
2610#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302611 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2612 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX,
2613 GFP_KERNEL);
2614
2615 if (!skb) {
2616 hddLog(VOS_TRACE_LEVEL_ERROR,
2617 FL("cfg80211_vendor_event_alloc failed"));
2618 return;
2619 }
2620 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2621 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2622
2623 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2624 pData->requestId) ||
2625 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2626 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2627 goto nla_put_failure;
2628 }
2629
2630 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302631 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302632 return;
2633
2634nla_put_failure:
2635 kfree_skb(skb);
2636 return;
2637}
2638
2639
2640static void wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(void *ctx,
2641 void *pMsg)
2642{
2643 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2644 struct sk_buff *skb = NULL;
2645 tpSirEXTScanSetSignificantChangeRspParams pData =
2646 (tpSirEXTScanSetSignificantChangeRspParams) pMsg;
2647
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302648 ENTER();
2649
2650 if (wlan_hdd_validate_context(pHddCtx)) {
2651 return;
2652 }
2653 if (!pMsg)
2654 {
2655 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302656 return;
2657 }
2658
2659 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302660#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2661 NULL,
2662#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302663 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2664 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX,
2665 GFP_KERNEL);
2666
2667 if (!skb) {
2668 hddLog(VOS_TRACE_LEVEL_ERROR,
2669 FL("cfg80211_vendor_event_alloc failed"));
2670 return;
2671 }
2672 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2673 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2674 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2675
2676 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2677 pData->requestId) ||
2678 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2679 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2680 goto nla_put_failure;
2681 }
2682
2683 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302684 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302685 return;
2686
2687nla_put_failure:
2688 kfree_skb(skb);
2689 return;
2690}
2691
2692
2693static void wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(void *ctx,
2694 void *pMsg)
2695{
2696 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2697 struct sk_buff *skb = NULL;
2698 tpSirEXTScanResetSignificantChangeRspParams pData =
2699 (tpSirEXTScanResetSignificantChangeRspParams) pMsg;
2700
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302701 ENTER();
2702
2703 if (wlan_hdd_validate_context(pHddCtx)) {
2704 return;
2705 }
2706 if (!pMsg)
2707 {
2708 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302709 return;
2710 }
2711
2712 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302713#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2714 NULL,
2715#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302716 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2717 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX,
2718 GFP_KERNEL);
2719
2720 if (!skb) {
2721 hddLog(VOS_TRACE_LEVEL_ERROR,
2722 FL("cfg80211_vendor_event_alloc failed"));
2723 return;
2724 }
2725 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2726 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2727 hddLog(VOS_TRACE_LEVEL_INFO, "Status (%u)", pData->status);
2728
2729 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2730 pData->requestId) ||
2731 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_STATUS, pData->status)) {
2732 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
2733 goto nla_put_failure;
2734 }
2735
2736 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302737 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302738 return;
2739
2740nla_put_failure:
2741 kfree_skb(skb);
2742 return;
2743}
2744
2745static void wlan_hdd_cfg80211_extscan_cached_results_ind(void *ctx,
2746 void *pMsg)
2747{
2748 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2749 struct sk_buff *skb = NULL;
2750 tANI_U32 i = 0, j, resultsPerEvent;
2751 tANI_S32 totalResults;
2752 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2753 tpSirWifiScanResult pSirWifiScanResult;
2754
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302755 ENTER();
2756
2757 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05302758 return;
2759 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302760 if (!pMsg)
2761 {
2762 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
2763 return;
2764 }
2765
Dino Mycle6fb96c12014-06-10 11:52:40 +05302766 totalResults = pData->numOfAps;
2767 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2768 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2769 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2770
2771 do{
2772 resultsPerEvent = ((totalResults >= EXTSCAN_MAX_CACHED_RESULTS_PER_IND) ?
2773 EXTSCAN_MAX_CACHED_RESULTS_PER_IND : totalResults);
2774 totalResults -= EXTSCAN_MAX_CACHED_RESULTS_PER_IND;
2775
2776 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302777#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2778 NULL,
2779#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302780 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2781 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX,
2782 GFP_KERNEL);
2783
2784 if (!skb) {
2785 hddLog(VOS_TRACE_LEVEL_ERROR,
2786 FL("cfg80211_vendor_event_alloc failed"));
2787 return;
2788 }
2789
2790 hddLog(VOS_TRACE_LEVEL_INFO, "resultsPerEvent (%u)", resultsPerEvent);
2791
2792 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2793 pData->requestId) ||
2794 nla_put_u32(skb,
2795 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2796 resultsPerEvent)) {
2797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2798 goto fail;
2799 }
2800 if (nla_put_u8(skb,
2801 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
2802 pData->moreData ? 1 : (totalResults > 0 ? 1 : 0 )))
2803 {
2804 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2805 goto fail;
2806 }
2807
2808 if (resultsPerEvent) {
2809 struct nlattr *aps;
2810
2811 aps = nla_nest_start(skb,
2812 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2813 if (!aps)
2814 {
2815 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2816 goto fail;
2817 }
2818
2819 for (j = 0; j < resultsPerEvent; j++, i++) {
2820 struct nlattr *ap;
2821 pSirWifiScanResult = (tpSirWifiScanResult) ((tANI_U8 *)
2822 pData->ap + ( i* sizeof(tSirWifiScanResult)));
2823
2824 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(%llu) "
2825 "Ssid (%s)"
2826 "Bssid: %pM "
2827 "Channel (%u)"
2828 "Rssi (%d)"
2829 "RTT (%u)"
2830 "RTT_SD (%u)",
2831 i,
2832 pSirWifiScanResult->ts,
2833 pSirWifiScanResult->ssid,
2834 pSirWifiScanResult->bssid,
2835 pSirWifiScanResult->channel,
2836 pSirWifiScanResult->rssi,
2837 pSirWifiScanResult->rtt,
2838 pSirWifiScanResult->rtt_sd);
2839
2840 ap = nla_nest_start(skb, j + 1);
2841 if (!ap)
2842 {
2843 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2844 goto fail;
2845 }
2846
2847 if (nla_put_u64(skb,
2848 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2849 pSirWifiScanResult->ts) )
2850 {
2851 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2852 goto fail;
2853 }
2854 if (nla_put(skb,
2855 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2856 sizeof(pSirWifiScanResult->ssid),
2857 pSirWifiScanResult->ssid) )
2858 {
2859 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2860 goto fail;
2861 }
2862 if (nla_put(skb,
2863 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
2864 sizeof(pSirWifiScanResult->bssid),
2865 pSirWifiScanResult->bssid) )
2866 {
2867 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2868 goto fail;
2869 }
2870 if (nla_put_u32(skb,
2871 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
2872 pSirWifiScanResult->channel) )
2873 {
2874 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2875 goto fail;
2876 }
Dasari Srinivas90747d72014-10-08 12:16:15 +05302877 if (nla_put_s32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05302878 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
2879 pSirWifiScanResult->rssi) )
2880 {
2881 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2882 goto fail;
2883 }
2884 if (nla_put_u32(skb,
2885 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
2886 pSirWifiScanResult->rtt) )
2887 {
2888 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2889 goto fail;
2890 }
2891 if (nla_put_u32(skb,
2892 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
2893 pSirWifiScanResult->rtt_sd))
2894 {
2895 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2896 goto fail;
2897 }
2898
2899 nla_nest_end(skb, ap);
2900 }
2901 nla_nest_end(skb, aps);
2902
2903 }
2904 cfg80211_vendor_event(skb, GFP_KERNEL);
2905 } while (totalResults > 0);
2906
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302907 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05302908 return;
2909fail:
2910 kfree_skb(skb);
2911 return;
2912}
2913
2914static void wlan_hdd_cfg80211_extscan_hotlist_match_ind(void *ctx,
2915 void *pMsg)
2916{
2917 tpSirWifiScanResultEvent pData = (tpSirWifiScanResultEvent) pMsg;
2918 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
2919 struct sk_buff *skb = NULL;
2920 tANI_U32 i;
2921
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05302922 ENTER();
2923
2924 if (wlan_hdd_validate_context(pHddCtx)) {
2925 return;
2926 }
2927 if (!pMsg)
2928 {
2929 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05302930 return;
2931 }
2932
2933 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05302934#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
2935 NULL,
2936#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05302937 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
2938 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX,
2939 GFP_KERNEL);
2940
2941 if (!skb) {
2942 hddLog(VOS_TRACE_LEVEL_ERROR,
2943 FL("cfg80211_vendor_event_alloc failed"));
2944 return;
2945 }
2946 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
2947 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
2948 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)", pData->numOfAps);
2949 hddLog(VOS_TRACE_LEVEL_INFO, "More Data (%u)", pData->moreData);
2950
2951 for (i = 0; i < pData->numOfAps; i++) {
2952 hddLog(VOS_TRACE_LEVEL_INFO, "[index=%u] Timestamp(0x%lld) "
2953 "Ssid (%s) "
2954 "Bssid (" MAC_ADDRESS_STR ") "
2955 "Channel (%u) "
2956 "Rssi (%d) "
2957 "RTT (%u) "
2958 "RTT_SD (%u) ",
2959 i,
2960 pData->ap[i].ts,
2961 pData->ap[i].ssid,
2962 MAC_ADDR_ARRAY(pData->ap[i].bssid),
2963 pData->ap[i].channel,
2964 pData->ap[i].rssi,
2965 pData->ap[i].rtt,
2966 pData->ap[i].rtt_sd);
2967 }
2968
2969 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
2970 pData->requestId) ||
2971 nla_put_u32(skb,
2972 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
2973 pData->numOfAps)) {
2974 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
2975 goto fail;
2976 }
2977 if (pData->numOfAps) {
2978 struct nlattr *aps;
2979
2980 aps = nla_nest_start(skb,
2981 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
2982 if (!aps)
2983 goto fail;
2984
2985 for (i = 0; i < pData->numOfAps; i++) {
2986 struct nlattr *ap;
2987
2988 ap = nla_nest_start(skb, i + 1);
2989 if (!ap)
2990 goto fail;
2991
2992 if (nla_put_u64(skb,
2993 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
2994 pData->ap[i].ts) ||
2995 nla_put(skb,
2996 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
2997 sizeof(pData->ap[i].ssid),
2998 pData->ap[i].ssid) ||
2999 nla_put(skb,
3000 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3001 sizeof(pData->ap[i].bssid),
3002 pData->ap[i].bssid) ||
3003 nla_put_u32(skb,
3004 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3005 pData->ap[i].channel) ||
3006 nla_put_s32(skb,
3007 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
3008 pData->ap[i].rssi) ||
3009 nla_put_u32(skb,
3010 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3011 pData->ap[i].rtt) ||
3012 nla_put_u32(skb,
3013 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3014 pData->ap[i].rtt_sd))
3015 goto fail;
3016
3017 nla_nest_end(skb, ap);
3018 }
3019 nla_nest_end(skb, aps);
3020
3021 if (nla_put_u8(skb,
3022 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3023 pData->moreData))
3024 goto fail;
3025 }
3026
3027 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303028 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303029 return;
3030
3031fail:
3032 kfree_skb(skb);
3033 return;
3034
3035}
3036static void wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(void *ctx,
3037 void *pMsg)
3038{
3039 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3040 struct sk_buff *skb = NULL;
3041 tANI_U32 i, j;
3042 tpSirWifiSignificantChangeEvent pData =
3043 (tpSirWifiSignificantChangeEvent) pMsg;
3044
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303045 ENTER();
3046
3047 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303048 return;
3049 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303050 if (!pMsg)
3051 {
3052 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
3053 return;
3054 }
3055
Dino Mycle6fb96c12014-06-10 11:52:40 +05303056 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303057#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3058 NULL,
3059#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303060 EXTSCAN_EVENT_BUF_SIZE,
3061 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX,
3062 GFP_KERNEL);
3063
3064 if (!skb) {
3065 hddLog(VOS_TRACE_LEVEL_ERROR,
3066 FL("cfg80211_vendor_event_alloc failed"));
3067 return;
3068 }
3069 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3070 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3071 hddLog(VOS_TRACE_LEVEL_INFO, "total List Size %u ", pData->numSigRssiBss);
3072 hddLog(VOS_TRACE_LEVEL_INFO, " CUrrent List size (%u)",
3073 pData->numSigRssiBss);
3074 hddLog(VOS_TRACE_LEVEL_INFO, "moreData (%u)", pData->moreData);
3075
3076 for (i = 0; i < pData->numSigRssiBss; i++) {
3077 hddLog(VOS_TRACE_LEVEL_INFO , "Rssi List [%d] BSSID: (%pM) Channel %u "
3078 " num RSSI %u ",
3079 i, pData->sigRssiResult[i].bssid,
3080 pData->sigRssiResult[i].channel,
3081 pData->sigRssiResult[i].numRssi);
3082
3083 for (j = 0; j < pData->sigRssiResult[i].numRssi; j++){
3084
3085 hddLog(VOS_TRACE_LEVEL_INFO,
3086 " [%d]",
Dino Myclec8f3f332014-07-21 16:48:27 +05303087 pData->sigRssiResult[i].rssi[j]);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303088
3089 }
3090 }
3091
3092
3093 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3094 pData->requestId) ||
3095 nla_put_u32(skb,
3096 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3097 pData->numSigRssiBss)) {
3098 hddLog(VOS_TRACE_LEVEL_ERROR, FL("put fail"));
3099 goto fail;
3100 }
3101
3102 if (pData->numSigRssiBss) {
3103 struct nlattr *aps;
3104 aps = nla_nest_start(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_LIST);
3105 if (!aps)
3106 goto fail;
3107 for (i = 0; i < pData->numSigRssiBss; i++) {
3108 struct nlattr *ap;
3109
3110 ap = nla_nest_start(skb, i);
3111 if (!ap)
3112 goto fail;
3113 if (nla_put(skb,
3114 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_BSSID,
3115 sizeof(tSirMacAddr), pData->sigRssiResult[i].bssid) ||
3116 nla_put_u32(skb,
3117 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_CHANNEL,
3118 pData->sigRssiResult[i].channel) ||
3119 nla_put_u32(skb,
3120 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_NUM_RSSI,
3121 pData->sigRssiResult[i].numRssi) ||
3122 nla_put(skb,
3123 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SIGNIFICANT_CHANGE_RESULT_RSSI_LIST,
3124 sizeof(s32) * pData->sigRssiResult[i].numRssi,
3125 pData->sigRssiResult[i].rssi))
3126 goto fail;
3127 nla_nest_end(skb, ap);
3128 }
3129 nla_nest_end(skb, aps);
3130 if (nla_put_u8(skb,
3131 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_MORE_DATA,
3132 pData->moreData))
3133 goto fail;
3134 }
3135 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303136 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303137 return;
3138fail:
3139 kfree_skb(skb);
3140 return;
3141}
3142
3143static void wlan_hdd_cfg80211_extscan_full_scan_result_event(void *ctx,
3144 void *pMsg)
3145{
3146 struct sk_buff *skb;
3147 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3148 tpSirWifiFullScanResultEvent pData =
3149 (tpSirWifiFullScanResultEvent) (pMsg);
3150
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303151 ENTER();
3152
3153 if (wlan_hdd_validate_context(pHddCtx)) {
3154 return;
3155 }
3156 if (!pMsg)
3157 {
3158 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303159 return;
3160 }
3161
3162 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303163#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3164 NULL,
3165#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303166 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3167 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX,
3168 GFP_KERNEL);
3169
3170 if (!skb) {
3171 hddLog(VOS_TRACE_LEVEL_ERROR,
3172 FL("cfg80211_vendor_event_alloc failed"));
3173 return;
3174 }
3175
3176 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3177 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%u)"), pData->requestId);
3178 hddLog(VOS_TRACE_LEVEL_INFO, FL("More Data (%u)"), pData->moreData);
3179 hddLog(VOS_TRACE_LEVEL_INFO, FL("AP Info: Timestamp(0x%llX) "
3180 "Ssid (%s)"
3181 "Bssid (" MAC_ADDRESS_STR ")"
3182 "Channel (%u)"
3183 "Rssi (%d)"
3184 "RTT (%u)"
3185 "RTT_SD (%u)"),
3186 pData->ap.ts,
3187 pData->ap.ssid,
3188 MAC_ADDR_ARRAY(pData->ap.bssid),
3189 pData->ap.channel,
3190 pData->ap.rssi,
3191 pData->ap.rtt,
3192 pData->ap.rtt_sd);
3193 hddLog(VOS_TRACE_LEVEL_INFO, "IE Length (%u)", pData->ieLength);
3194 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3195 pData->requestId) ||
3196 nla_put_u64(skb,
3197 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_TIME_STAMP,
3198 pData->ap.ts) ||
3199 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_SSID,
3200 sizeof(pData->ap.ssid),
3201 pData->ap.ssid) ||
3202 nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BSSID,
3203 WNI_CFG_BSSID_LEN,
3204 pData->ap.bssid) ||
3205 nla_put_u32(skb,
3206 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CHANNEL,
3207 pData->ap.channel) ||
Dasari Srinivas90747d72014-10-08 12:16:15 +05303208 nla_put_s32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RSSI,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303209 pData->ap.rssi) ||
3210 nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT,
3211 pData->ap.rtt) ||
3212 nla_put_u32(skb,
3213 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_RTT_SD,
3214 pData->ap.rtt_sd) ||
3215 nla_put_u16(skb,
3216 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD,
3217 pData->ap.beaconPeriod) ||
3218 nla_put_u16(skb,
3219 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_CAPABILITY,
3220 pData->ap.capability) ||
3221 nla_put_u32(skb,
3222 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_LENGTH,
3223 pData->ieLength))
3224 {
3225 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3226 goto nla_put_failure;
3227 }
3228 if (nla_put(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_IE_DATA,
3229 pData->ieLength,
3230 pData->ie))
3231 {
3232 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3233 goto nla_put_failure;
3234 }
3235
3236 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303237 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303238 return;
3239
3240nla_put_failure:
3241 kfree_skb(skb);
3242 return;
3243}
3244
3245static void wlan_hdd_cfg80211_extscan_scan_res_available_event(void *ctx,
3246 void *pMsg)
3247{
3248 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3249 struct sk_buff *skb = NULL;
3250 tpSirEXTScanResultsAvailableIndParams pData =
3251 (tpSirEXTScanResultsAvailableIndParams) pMsg;
3252
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303253 ENTER();
3254
3255 if (wlan_hdd_validate_context(pHddCtx)){
3256 return;
3257 }
3258 if (!pMsg)
3259 {
3260 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303261 return;
3262 }
3263
3264 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303265#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3266 NULL,
3267#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303268 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3269 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX,
3270 GFP_KERNEL);
3271
3272 if (!skb) {
3273 hddLog(VOS_TRACE_LEVEL_ERROR,
3274 FL("cfg80211_vendor_event_alloc failed"));
3275 return;
3276 }
3277
3278 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3279 hddLog(VOS_TRACE_LEVEL_INFO, "Req Id (%u)", pData->requestId);
3280 hddLog(VOS_TRACE_LEVEL_INFO, "Num results (%u)",
3281 pData->numResultsAvailable);
3282 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3283 pData->requestId) ||
3284 nla_put_u32(skb,
3285 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_RESULTS_AVAILABLE,
3286 pData->numResultsAvailable)) {
3287 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3288 goto nla_put_failure;
3289 }
3290
3291 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303292 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303293 return;
3294
3295nla_put_failure:
3296 kfree_skb(skb);
3297 return;
3298}
3299
3300static void wlan_hdd_cfg80211_extscan_scan_progress_event(void *ctx, void *pMsg)
3301{
3302 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3303 struct sk_buff *skb = NULL;
3304 tpSirEXTScanProgressIndParams pData =
3305 (tpSirEXTScanProgressIndParams) pMsg;
3306
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303307 ENTER();
3308
3309 if (wlan_hdd_validate_context(pHddCtx)){
3310 return;
3311 }
3312 if (!pMsg)
3313 {
3314 hddLog(VOS_TRACE_LEVEL_ERROR, FL("pMsg is null"));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303315 return;
3316 }
3317
3318 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05303319#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
3320 NULL,
3321#endif
Dino Mycle6fb96c12014-06-10 11:52:40 +05303322 EXTSCAN_EVENT_BUF_SIZE + NLMSG_HDRLEN,
3323 QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX,
3324 GFP_KERNEL);
3325
3326 if (!skb) {
3327 hddLog(VOS_TRACE_LEVEL_ERROR,
3328 FL("cfg80211_vendor_event_alloc failed"));
3329 return;
3330 }
3331 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
3332 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event type (%u)",
3333 pData->extScanEventType);
3334 hddLog(VOS_TRACE_LEVEL_INFO, "Scan event status (%u)",
3335 pData->status);
3336
3337 if (nla_put_u8(skb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_TYPE,
3338 pData->extScanEventType) ||
3339 nla_put_u32(skb,
Dasari Srinivas5a288652014-06-30 17:13:22 +05303340 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_REQUEST_ID,
3341 pData->requestId) ||
3342 nla_put_u32(skb,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303343 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_EVENT_STATUS,
3344 pData->status)) {
3345 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3346 goto nla_put_failure;
3347 }
3348
3349 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303350 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303351 return;
3352
3353nla_put_failure:
3354 kfree_skb(skb);
3355 return;
3356}
3357
3358void wlan_hdd_cfg80211_extscan_callback(void *ctx, const tANI_U16 evType,
3359 void *pMsg)
3360{
3361 hdd_context_t *pHddCtx = (hdd_context_t *)ctx;
3362
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303363 ENTER();
3364
Dino Mycle6fb96c12014-06-10 11:52:40 +05303365 if (wlan_hdd_validate_context(pHddCtx)) {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303366 return;
3367 }
3368
3369 hddLog(VOS_TRACE_LEVEL_INFO, FL("Rcvd Event (%d)"), evType);
3370
3371
3372 switch(evType) {
3373 case SIR_HAL_EXTSCAN_START_RSP:
3374 wlan_hdd_cfg80211_extscan_start_rsp(ctx, pMsg);
3375 break;
3376
3377 case SIR_HAL_EXTSCAN_STOP_RSP:
3378 wlan_hdd_cfg80211_extscan_stop_rsp(ctx, pMsg);
3379 break;
3380 case SIR_HAL_EXTSCAN_GET_CACHED_RESULTS_RSP:
3381 /* There is no need to send this response to upper layer
3382 Just log the message */
3383 hddLog(VOS_TRACE_LEVEL_INFO,
3384 FL("Rcvd SIR_HAL_EXTSCAN_CACHED_RESULTS_RSP"));
3385 break;
3386 case SIR_HAL_EXTSCAN_SET_BSS_HOTLIST_RSP:
3387 wlan_hdd_cfg80211_extscan_set_bss_hotlist_rsp(ctx, pMsg);
3388 break;
3389
3390 case SIR_HAL_EXTSCAN_RESET_BSS_HOTLIST_RSP:
3391 wlan_hdd_cfg80211_extscan_reset_bss_hotlist_rsp(ctx, pMsg);
3392 break;
3393
3394 case SIR_HAL_EXTSCAN_SET_SIGNF_RSSI_CHANGE_RSP:
3395 wlan_hdd_cfg80211_extscan_set_signf_wifi_change_rsp(ctx, pMsg);
3396 break;
3397
3398 case SIR_HAL_EXTSCAN_RESET_SIGNF_RSSI_CHANGE_RSP:
3399 wlan_hdd_cfg80211_extscan_reset_signf_wifi_change_rsp(ctx, pMsg);
3400 break;
3401 case SIR_HAL_EXTSCAN_GET_CAPABILITIES_RSP:
3402 wlan_hdd_cfg80211_extscan_get_capabilities_ind(ctx, pMsg);
3403 break;
3404 case SIR_HAL_EXTSCAN_PROGRESS_IND:
3405 wlan_hdd_cfg80211_extscan_scan_progress_event(ctx, pMsg);
3406 break;
3407 case SIR_HAL_EXTSCAN_SCAN_AVAILABLE_IND:
3408 wlan_hdd_cfg80211_extscan_scan_res_available_event(ctx, pMsg);
3409 break;
3410 case SIR_HAL_EXTSCAN_SCAN_RESULT_IND:
3411 wlan_hdd_cfg80211_extscan_cached_results_ind(ctx, pMsg);
3412 break;
3413 case SIR_HAL_EXTSCAN_HOTLIST_MATCH_IND:
3414 wlan_hdd_cfg80211_extscan_hotlist_match_ind(ctx, pMsg);
3415 break;
3416 case SIR_HAL_EXTSCAN_SIGNF_WIFI_CHANGE_IND:
3417 wlan_hdd_cfg80211_extscan_signif_wifi_change_results_ind(ctx, pMsg);
3418 break;
3419 case SIR_HAL_EXTSCAN_FULL_SCAN_RESULT_IND:
3420 wlan_hdd_cfg80211_extscan_full_scan_result_event(ctx, pMsg);
3421 break;
3422 default:
3423 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid event type %d "), evType);
3424 break;
3425 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303426 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303427}
3428
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303429static int __wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3430 struct wireless_dev *wdev,
3431 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303432{
Dino Myclee8843b32014-07-04 14:21:45 +05303433 tSirGetEXTScanCapabilitiesReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303434 struct net_device *dev = wdev->netdev;
3435 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3436 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3437 struct nlattr
3438 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3439 eHalStatus status;
3440
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303441 ENTER();
3442
Dino Mycle6fb96c12014-06-10 11:52:40 +05303443 status = wlan_hdd_validate_context(pHddCtx);
3444 if (0 != status)
3445 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303446 return -EINVAL;
3447 }
Dino Myclee8843b32014-07-04 14:21:45 +05303448 /* check the EXTScan Capability */
3449 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3450 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3451 {
3452 hddLog(VOS_TRACE_LEVEL_ERROR,
3453 FL("EXTScan not enabled/supported by Firmware"));
3454 return -EINVAL;
3455 }
3456
Dino Mycle6fb96c12014-06-10 11:52:40 +05303457 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3458 data, dataLen,
3459 wlan_hdd_extscan_config_policy)) {
3460 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3461 return -EINVAL;
3462 }
3463
3464 /* Parse and fetch request Id */
3465 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3466 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3467 return -EINVAL;
3468 }
3469
Dino Mycle6fb96c12014-06-10 11:52:40 +05303470
Dino Myclee8843b32014-07-04 14:21:45 +05303471 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303472 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05303473 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303474
Dino Myclee8843b32014-07-04 14:21:45 +05303475 reqMsg.sessionId = pAdapter->sessionId;
3476 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303477
Dino Myclee8843b32014-07-04 14:21:45 +05303478 status = sme_EXTScanGetCapabilities(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303479 if (!HAL_STATUS_SUCCESS(status)) {
3480 hddLog(VOS_TRACE_LEVEL_ERROR,
3481 FL("sme_EXTScanGetCapabilities failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303482 return -EINVAL;
3483 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303484 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303485 return 0;
3486}
3487
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303488static int wlan_hdd_cfg80211_extscan_get_capabilities(struct wiphy *wiphy,
3489 struct wireless_dev *wdev,
3490 const void *data, int dataLen)
3491{
3492 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303493
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303494 vos_ssr_protect(__func__);
3495 ret = __wlan_hdd_cfg80211_extscan_get_capabilities(wiphy, wdev, data, dataLen);
3496 vos_ssr_unprotect(__func__);
3497
3498 return ret;
3499}
3500
3501static int __wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3502 struct wireless_dev *wdev,
3503 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303504{
Dino Myclee8843b32014-07-04 14:21:45 +05303505 tSirEXTScanGetCachedResultsReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303506 struct net_device *dev = wdev->netdev;
3507 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3508 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3509 struct nlattr
3510 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3511 eHalStatus status;
3512
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303513 ENTER();
3514
Dino Mycle6fb96c12014-06-10 11:52:40 +05303515 status = wlan_hdd_validate_context(pHddCtx);
3516 if (0 != status)
3517 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303518 return -EINVAL;
3519 }
Dino Myclee8843b32014-07-04 14:21:45 +05303520 /* check the EXTScan Capability */
3521 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3522 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3523 {
3524 hddLog(VOS_TRACE_LEVEL_ERROR,
3525 FL("EXTScan not enabled/supported by Firmware"));
3526 return -EINVAL;
3527 }
3528
Dino Mycle6fb96c12014-06-10 11:52:40 +05303529 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3530 data, dataLen,
3531 wlan_hdd_extscan_config_policy)) {
3532 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3533 return -EINVAL;
3534 }
3535 /* Parse and fetch request Id */
3536 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3537 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3538 return -EINVAL;
3539 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303540
Dino Myclee8843b32014-07-04 14:21:45 +05303541 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303542 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3543
Dino Myclee8843b32014-07-04 14:21:45 +05303544 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303545
Dino Myclee8843b32014-07-04 14:21:45 +05303546 reqMsg.sessionId = pAdapter->sessionId;
3547 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303548
3549 /* Parse and fetch flush parameter */
3550 if (!tb
3551 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH])
3552 {
3553 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr flush failed"));
3554 goto failed;
3555 }
Dino Myclee8843b32014-07-04 14:21:45 +05303556 reqMsg.flush = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05303557 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_CACHED_SCAN_RESULTS_CONFIG_PARAM_FLUSH]);
3558
Dino Myclee8843b32014-07-04 14:21:45 +05303559 hddLog(VOS_TRACE_LEVEL_INFO, FL("Flush (%d)"), reqMsg.flush);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303560
Dino Myclee8843b32014-07-04 14:21:45 +05303561 status = sme_getCachedResults(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303562 if (!HAL_STATUS_SUCCESS(status)) {
3563 hddLog(VOS_TRACE_LEVEL_ERROR,
3564 FL("sme_getCachedResults failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05303565 return -EINVAL;
3566 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303567 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303568 return 0;
3569
3570failed:
Dino Mycle6fb96c12014-06-10 11:52:40 +05303571 return -EINVAL;
3572}
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303573static int wlan_hdd_cfg80211_extscan_get_cached_results(struct wiphy *wiphy,
3574 struct wireless_dev *wdev,
3575 const void *data, int dataLen)
3576{
3577 int ret = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303578
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303579 vos_ssr_protect(__func__);
3580 ret = __wlan_hdd_cfg80211_extscan_get_cached_results(wiphy, wdev, data, dataLen);
3581 vos_ssr_unprotect(__func__);
3582
3583 return ret;
3584}
3585
3586static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303587 struct wireless_dev *wdev,
Edhar, Mahesh Kumared8631f2015-01-20 14:31:47 +05303588 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303589{
3590 tpSirEXTScanSetBssidHotListReqParams pReqMsg = NULL;
3591 struct net_device *dev = wdev->netdev;
3592 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3593 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3594 struct nlattr
3595 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3596 struct nlattr
3597 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3598 struct nlattr *apTh;
3599 eHalStatus status;
3600 tANI_U8 i = 0;
3601 int rem;
3602
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303603 ENTER();
3604
Dino Mycle6fb96c12014-06-10 11:52:40 +05303605 status = wlan_hdd_validate_context(pHddCtx);
3606 if (0 != status)
3607 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303608 return -EINVAL;
3609 }
Dino Myclee8843b32014-07-04 14:21:45 +05303610 /* check the EXTScan Capability */
3611 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3612 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3613 {
3614 hddLog(VOS_TRACE_LEVEL_ERROR,
3615 FL("EXTScan not enabled/supported by Firmware"));
3616 return -EINVAL;
3617 }
3618
Dino Mycle6fb96c12014-06-10 11:52:40 +05303619 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3620 data, dataLen,
3621 wlan_hdd_extscan_config_policy)) {
3622 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3623 return -EINVAL;
3624 }
3625
3626 /* Parse and fetch request Id */
3627 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3628 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3629 return -EINVAL;
3630 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303631 pReqMsg = (tpSirEXTScanSetBssidHotListReqParams)
3632 vos_mem_malloc(sizeof(*pReqMsg));
3633 if (!pReqMsg) {
3634 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3635 return -ENOMEM;
3636 }
3637
Dino Myclee8843b32014-07-04 14:21:45 +05303638
Dino Mycle6fb96c12014-06-10 11:52:40 +05303639 pReqMsg->requestId = nla_get_u32(
3640 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3641 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3642
3643 /* Parse and fetch number of APs */
3644 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]) {
3645 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3646 goto fail;
3647 }
3648
3649 pReqMsg->sessionId = pAdapter->sessionId;
3650 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3651
3652 pReqMsg->numAp = nla_get_u32(
3653 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
3654 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3655
3656 nla_for_each_nested(apTh,
3657 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3658 if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3659 nla_data(apTh), nla_len(apTh),
3660 NULL)) {
3661 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3662 goto fail;
3663 }
3664
3665 /* Parse and fetch MAC address */
3666 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3667 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3668 goto fail;
3669 }
3670 memcpy(pReqMsg->ap[i].bssid, nla_data(
3671 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3672 sizeof(tSirMacAddr));
3673 hddLog(VOS_TRACE_LEVEL_INFO, FL("BSSID: %pM "), pReqMsg->ap[i].bssid);
3674
3675 /* Parse and fetch low RSSI */
3676 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3677 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3678 goto fail;
3679 }
3680 pReqMsg->ap[i].low = nla_get_s32(
3681 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3682 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3683
3684 /* Parse and fetch high RSSI */
3685 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3686 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3687 goto fail;
3688 }
3689 pReqMsg->ap[i].high = nla_get_s32(
3690 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3691 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI High (%d)"),
3692 pReqMsg->ap[i].high);
3693
3694 /* Parse and fetch channel */
3695 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3696 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3697 goto fail;
3698 }
3699 pReqMsg->ap[i].channel = nla_get_u32(
3700 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3701 hddLog(VOS_TRACE_LEVEL_INFO,
3702 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3703 i++;
3704 }
3705 status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
3706 if (!HAL_STATUS_SUCCESS(status)) {
3707 hddLog(VOS_TRACE_LEVEL_ERROR,
3708 FL("sme_SetBssHotlist failed(err=%d)"), status);
3709 vos_mem_free(pReqMsg);
3710 return -EINVAL;
3711 }
3712
Dino Myclee8843b32014-07-04 14:21:45 +05303713 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303714 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303715 return 0;
3716
3717fail:
3718 vos_mem_free(pReqMsg);
3719 return -EINVAL;
3720}
3721
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303722static int wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
3723 struct wireless_dev *wdev,
3724 const void *data, int dataLen)
3725{
3726 int ret = 0;
3727
3728 vos_ssr_protect(__func__);
3729 ret = __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(wiphy, wdev, data,
3730 dataLen);
3731 vos_ssr_unprotect(__func__);
3732
3733 return ret;
3734}
3735
3736static int __wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303737 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303738 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303739{
3740 tpSirEXTScanSetSignificantChangeReqParams pReqMsg = NULL;
3741 struct net_device *dev = wdev->netdev;
3742 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
3743 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3744 struct nlattr
3745 *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3746 struct nlattr
3747 *tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3748 struct nlattr *apTh;
3749 eHalStatus status;
3750 int i = 0;
3751 int rem;
3752
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303753 ENTER();
3754
Dino Mycle6fb96c12014-06-10 11:52:40 +05303755 status = wlan_hdd_validate_context(pHddCtx);
3756 if (0 != status)
3757 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303758 return -EINVAL;
3759 }
Dino Myclee8843b32014-07-04 14:21:45 +05303760 /* check the EXTScan Capability */
3761 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
3762 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
3763 {
3764 hddLog(VOS_TRACE_LEVEL_ERROR,
3765 FL("EXTScan not enabled/supported by Firmware"));
3766 return -EINVAL;
3767 }
3768
Dino Mycle6fb96c12014-06-10 11:52:40 +05303769 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3770 data, dataLen,
3771 wlan_hdd_extscan_config_policy)) {
3772 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3773 return -EINVAL;
3774 }
3775
3776 /* Parse and fetch request Id */
3777 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3778 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3779 return -EINVAL;
3780 }
Dino Mycle6fb96c12014-06-10 11:52:40 +05303781 pReqMsg = (tpSirEXTScanSetSignificantChangeReqParams)
Dino Myclee8843b32014-07-04 14:21:45 +05303782 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05303783 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05303784 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
3785 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303786 }
3787
Dino Myclee8843b32014-07-04 14:21:45 +05303788
3789
Dino Mycle6fb96c12014-06-10 11:52:40 +05303790 pReqMsg->requestId = nla_get_u32(
3791 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3792 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
3793
3794 /* Parse and fetch RSSI sample size */
3795 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE])
3796 {
3797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr RSSI sample size failed"));
3798 goto fail;
3799 }
3800 pReqMsg->rssiSampleSize = nla_get_u32(
3801 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_RSSI_SAMPLE_SIZE]);
3802 hddLog(VOS_TRACE_LEVEL_INFO,
3803 FL("RSSI sample size (%u)"), pReqMsg->rssiSampleSize);
3804
3805 /* Parse and fetch lost AP sample size */
3806 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE])
3807 {
3808 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr lost AP sample size failed"));
3809 goto fail;
3810 }
3811 pReqMsg->lostApSampleSize = nla_get_u32(
3812 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE]);
3813 hddLog(VOS_TRACE_LEVEL_INFO,
3814 FL("Lost AP sample size (%u)"), pReqMsg->lostApSampleSize);
3815 /* Parse and fetch minimum Breaching */
3816 if (!tb
3817 [QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]) {
3818 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr minBreaching failed"));
3819 goto fail;
3820 }
3821 pReqMsg->minBreaching = nla_get_u32(
3822 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING]);
3823 hddLog(VOS_TRACE_LEVEL_INFO, FL(" Breaching (%d)"), pReqMsg->minBreaching);
3824
3825 /* Parse and fetch number of APs */
3826 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]) {
3827 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of AP failed"));
3828 goto fail;
3829 }
3830 pReqMsg->numAp = nla_get_u32(
3831 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
3832 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
3833
3834 pReqMsg->sessionId = pAdapter->sessionId;
3835 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
3836
3837 nla_for_each_nested(apTh,
3838 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
3839 if(nla_parse(tb2,
3840 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3841 nla_data(apTh), nla_len(apTh),
3842 NULL)) {
3843 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
3844 goto fail;
3845 }
3846
3847 /* Parse and fetch MAC address */
3848 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]) {
3849 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac address failed"));
3850 goto fail;
3851 }
3852 memcpy(pReqMsg->ap[i].bssid, nla_data(
3853 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_BSSID]),
3854 sizeof(tSirMacAddr));
3855
3856 /* Parse and fetch low RSSI */
3857 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]) {
3858 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr low RSSI failed"));
3859 goto fail;
3860 }
3861 pReqMsg->ap[i].low = nla_get_s32(
3862 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_LOW]);
3863 hddLog(VOS_TRACE_LEVEL_INFO, FL("RSSI low (%d)"), pReqMsg->ap[i].low);
3864
3865 /* Parse and fetch high RSSI */
3866 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]) {
3867 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr high RSSI failed"));
3868 goto fail;
3869 }
3870 pReqMsg->ap[i].high = nla_get_s32(
3871 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_RSSI_HIGH]);
3872 hddLog(VOS_TRACE_LEVEL_INFO,
3873 FL("RSSI High (%d)"), pReqMsg->ap[i].high);
3874
3875 /* Parse and fetch channel */
3876 if (!tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]) {
3877 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
3878 goto fail;
3879 }
3880 pReqMsg->ap[i].channel = nla_get_u32(
3881 tb2[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM_CHANNEL]);
3882 hddLog(VOS_TRACE_LEVEL_INFO,
3883 FL("Channel (%u)"), pReqMsg->ap[i].channel);
3884 i++;
3885 }
3886
3887 status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
3888 if (!HAL_STATUS_SUCCESS(status)) {
3889 hddLog(VOS_TRACE_LEVEL_ERROR,
3890 FL("sme_SetSignificantChange failed(err=%d)"), status);
3891 vos_mem_free(pReqMsg);
3892 return -EINVAL;
3893 }
Dino Myclee8843b32014-07-04 14:21:45 +05303894 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303895 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05303896 return 0;
3897
3898fail:
3899 vos_mem_free(pReqMsg);
3900 return -EINVAL;
3901}
3902
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05303903static int wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiphy,
3904 struct wireless_dev *wdev,
3905 const void *data, int dataLen)
3906{
3907 int ret = 0;
3908
3909 vos_ssr_protect(__func__);
3910 ret = __wlan_hdd_cfg80211_extscan_set_significant_change(wiphy, wdev, data,
3911 dataLen);
3912 vos_ssr_unprotect(__func__);
3913
3914 return ret;
3915}
3916
3917static int __wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05303918 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05303919 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05303920{
3921 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
3922 tANI_U32 ChannelList[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
3923 tANI_U8 numChannels = 0;
3924 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
3925 tANI_U32 requestId;
3926 tWifiBand wifiBand;
3927 eHalStatus status;
3928 struct sk_buff *replySkb;
3929 tANI_U8 i;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303930 int ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05303931
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303932 ENTER();
3933
Dino Mycle6fb96c12014-06-10 11:52:40 +05303934 status = wlan_hdd_validate_context(pHddCtx);
3935 if (0 != status)
3936 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05303937 return -EINVAL;
3938 }
Dino Myclee8843b32014-07-04 14:21:45 +05303939
Dino Mycle6fb96c12014-06-10 11:52:40 +05303940 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
3941 data, dataLen,
3942 wlan_hdd_extscan_config_policy)) {
3943 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
3944 return -EINVAL;
3945 }
3946
3947 /* Parse and fetch request Id */
3948 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
3949 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
3950 return -EINVAL;
3951 }
3952 requestId = nla_get_u32(
3953 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
3954 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), requestId);
3955
3956 /* Parse and fetch wifi band */
3957 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND])
3958 {
3959 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
3960 return -EINVAL;
3961 }
3962 wifiBand = nla_get_u32(
3963 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_GET_VALID_CHANNELS_CONFIG_PARAM_WIFI_BAND]);
3964 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"), wifiBand);
3965
3966 status = sme_GetValidChannelsByBand((tHalHandle)(pHddCtx->hHal),
3967 wifiBand, ChannelList,
3968 &numChannels);
3969 if (eHAL_STATUS_SUCCESS != status) {
3970 hddLog(VOS_TRACE_LEVEL_ERROR,
3971 FL("sme_GetValidChannelsByBand failed (err=%d)"), status);
3972 return -EINVAL;
3973 }
3974 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of channels (%d)"), numChannels);
3975 for (i = 0; i < numChannels; i++)
3976 hddLog(VOS_TRACE_LEVEL_INFO, "Channel: %u ", ChannelList[i]);
3977
3978 replySkb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
3979 sizeof(u32) * numChannels +
3980 NLMSG_HDRLEN);
3981
3982 if (!replySkb) {
3983 hddLog(VOS_TRACE_LEVEL_ERROR,
3984 FL("valid channels: buffer alloc fail"));
3985 return -EINVAL;
3986 }
3987 if (nla_put_u32(replySkb,
3988 QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_NUM_CHANNELS,
3989 numChannels) ||
3990 nla_put(replySkb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_CHANNELS,
3991 sizeof(u32) * numChannels, ChannelList)) {
3992
3993 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
3994 kfree_skb(replySkb);
3995 return -EINVAL;
3996 }
3997
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05303998 ret = cfg80211_vendor_cmd_reply(replySkb);
3999
4000 EXIT();
4001 return ret;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304002}
4003
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304004static int wlan_hdd_cfg80211_extscan_get_valid_channels(struct wiphy *wiphy,
4005 struct wireless_dev *wdev,
4006 const void *data, int dataLen)
4007{
4008 int ret = 0;
4009
4010 vos_ssr_protect(__func__);
4011 ret = __wlan_hdd_cfg80211_extscan_get_valid_channels(wiphy, wdev, data,
4012 dataLen);
4013 vos_ssr_unprotect(__func__);
4014
4015 return ret;
4016}
4017
4018static int __wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304019 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304020 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304021{
Dino Myclee8843b32014-07-04 14:21:45 +05304022 tpSirEXTScanStartReqParams pReqMsg = NULL;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304023 struct net_device *dev = wdev->netdev;
4024 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4025 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4026 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4027 struct nlattr *bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4028 struct nlattr *channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4029 struct nlattr *buckets;
4030 struct nlattr *channels;
4031 int rem1;
4032 int rem2;
4033 eHalStatus status;
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304034 tANI_U32 j = 0, index = 0;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304035
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304036 ENTER();
4037
Dino Mycle6fb96c12014-06-10 11:52:40 +05304038 status = wlan_hdd_validate_context(pHddCtx);
4039 if (0 != status)
4040 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304041 return -EINVAL;
4042 }
Dino Myclee8843b32014-07-04 14:21:45 +05304043 /* check the EXTScan Capability */
4044 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4045 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4046 {
4047 hddLog(VOS_TRACE_LEVEL_ERROR,
4048 FL("EXTScan not enabled/supported by Firmware"));
4049 return -EINVAL;
4050 }
4051
Dino Mycle6fb96c12014-06-10 11:52:40 +05304052 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4053 data, dataLen,
4054 wlan_hdd_extscan_config_policy)) {
4055 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4056 return -EINVAL;
4057 }
4058
4059 /* Parse and fetch request Id */
4060 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4061 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4062 return -EINVAL;
4063 }
4064
Dino Myclee8843b32014-07-04 14:21:45 +05304065 pReqMsg = (tpSirEXTScanStartReqParams)
4066 vos_mem_malloc(sizeof(*pReqMsg));
Dino Mycle6fb96c12014-06-10 11:52:40 +05304067 if (!pReqMsg) {
Dino Myclee8843b32014-07-04 14:21:45 +05304068 hddLog(VOS_TRACE_LEVEL_ERROR, FL("vos_mem_malloc failed"));
4069 return -ENOMEM;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304070 }
4071
4072 pReqMsg->requestId = nla_get_u32(
4073 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
4074 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), pReqMsg->requestId);
4075
4076 pReqMsg->sessionId = pAdapter->sessionId;
4077 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), pReqMsg->sessionId);
4078
4079 /* Parse and fetch base period */
4080 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]) {
4081 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr base period failed"));
4082 goto fail;
4083 }
4084 pReqMsg->basePeriod = nla_get_u32(
4085 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_BASE_PERIOD]);
4086 hddLog(VOS_TRACE_LEVEL_INFO, FL("Base Period (%d)"),
4087 pReqMsg->basePeriod);
4088
4089 /* Parse and fetch max AP per scan */
4090 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]) {
4091 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr max_ap_per_scan failed"));
4092 goto fail;
4093 }
4094 pReqMsg->maxAPperScan = nla_get_u32(
4095 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_MAX_AP_PER_SCAN]);
4096 hddLog(VOS_TRACE_LEVEL_INFO, FL("Max AP per Scan (%d)"),
4097 pReqMsg->maxAPperScan);
4098
4099 /* Parse and fetch report threshold */
4100 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]) {
4101 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report_threshold failed"));
4102 goto fail;
4103 }
4104 pReqMsg->reportThreshold = nla_get_u8(
4105 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_REPORT_THRESHOLD]);
4106 hddLog(VOS_TRACE_LEVEL_INFO, FL("Report Threshold (%d)"),
4107 pReqMsg->reportThreshold);
4108
4109 /* Parse and fetch number of buckets */
4110 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]) {
4111 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr number of buckets failed"));
4112 goto fail;
4113 }
4114 pReqMsg->numBuckets = nla_get_u8(
4115 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SCAN_CMD_PARAMS_NUM_BUCKETS]);
4116 if (pReqMsg->numBuckets > WLAN_EXTSCAN_MAX_BUCKETS) {
4117 hddLog(VOS_TRACE_LEVEL_WARN, FL("Exceeded MAX number of buckets "
4118 "Setting numBuckets to %u"), WLAN_EXTSCAN_MAX_BUCKETS);
4119 pReqMsg->numBuckets = WLAN_EXTSCAN_MAX_BUCKETS;
4120 }
4121 hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of Buckets (%d)"),
4122 pReqMsg->numBuckets);
4123 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC]) {
4124 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket spec failed"));
4125 goto fail;
4126 }
4127
4128 nla_for_each_nested(buckets,
4129 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC], rem1) {
4130 if(nla_parse(bucket,
4131 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4132 nla_data(buckets), nla_len(buckets), NULL)) { //policy
4133 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4134 goto fail;
4135 }
4136
4137 /* Parse and fetch bucket spec */
4138 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]) {
4139 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bucket index failed"));
4140 goto fail;
4141 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304142
4143 pReqMsg->buckets[index].bucket = nla_get_u8(
4144 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_INDEX]);
4145
4146 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bucket spec Index (%d)"),
4147 pReqMsg->buckets[index].bucket);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304148
4149 /* Parse and fetch wifi band */
4150 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]) {
4151 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr wifi band failed"));
4152 goto fail;
4153 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304154 pReqMsg->buckets[index].band = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304155 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_BAND]);
4156 hddLog(VOS_TRACE_LEVEL_INFO, FL("Wifi band (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304157 pReqMsg->buckets[index].band);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304158
4159 /* Parse and fetch period */
4160 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]) {
4161 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr period failed"));
4162 goto fail;
4163 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304164 pReqMsg->buckets[index].period = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304165 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_PERIOD]);
4166 hddLog(VOS_TRACE_LEVEL_INFO, FL("period (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304167 pReqMsg->buckets[index].period);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304168
4169 /* Parse and fetch report events */
4170 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]) {
4171 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr report events failed"));
4172 goto fail;
4173 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304174 pReqMsg->buckets[index].reportEvents = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304175 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_REPORT_EVENTS]);
4176 hddLog(VOS_TRACE_LEVEL_INFO, FL("report events (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304177 pReqMsg->buckets[index].reportEvents);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304178
4179 /* Parse and fetch number of channels */
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304180 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS])
4181 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304182 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr num channels failed"));
4183 goto fail;
4184 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304185 pReqMsg->buckets[index].numChannels = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304186 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BUCKET_SPEC_NUM_CHANNEL_SPECS]);
4187 hddLog(VOS_TRACE_LEVEL_INFO, FL("num channels (%d)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304188 pReqMsg->buckets[index].numChannels);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304189
4190 if (!bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC]) {
4191 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel spec failed"));
4192 goto fail;
4193 }
4194
4195 j = 0;
4196 nla_for_each_nested(channels,
4197 bucket[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC], rem2) {
4198 if(nla_parse(channel,
4199 QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4200 nla_data(channels), nla_len(channels),
4201 NULL)) { //wlan_hdd_extscan_config_policy here
4202 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_parse failed"));
4203 goto fail;
4204 }
4205
4206 /* Parse and fetch channel */
4207 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]) {
4208 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4209 goto fail;
4210 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304211 pReqMsg->buckets[index].channels[j].channel = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304212 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_CHANNEL]);
4213 hddLog(VOS_TRACE_LEVEL_INFO, FL("channel (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304214 pReqMsg->buckets[index].channels[j].channel);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304215
4216 /* Parse and fetch dwell time */
4217 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]) {
4218 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dwelltime failed"));
4219 goto fail;
4220 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304221 pReqMsg->buckets[index].channels[j].dwellTimeMs = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304222 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_DWELL_TIME]);
4223 hddLog(VOS_TRACE_LEVEL_INFO, FL("Dwell time (%u ms)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304224 pReqMsg->buckets[index].channels[j].dwellTimeMs);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304225
4226 /* Parse and fetch channel spec passive */
4227 if (!channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]) {
4228 hddLog(VOS_TRACE_LEVEL_ERROR,
4229 FL("attr channel spec passive failed"));
4230 goto fail;
4231 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304232 pReqMsg->buckets[index].channels[j].passive = nla_get_u8(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304233 channel[QCA_WLAN_VENDOR_ATTR_EXTSCAN_CHANNEL_SPEC_PASSIVE]);
4234 hddLog(VOS_TRACE_LEVEL_INFO, FL("Chnl spec passive (%u)"),
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304235 pReqMsg->buckets[index].channels[j].passive);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304236 j++;
4237 }
Dasari Srinivas8b2ce272014-09-16 16:57:30 +05304238 index++;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304239 }
4240 status = sme_EXTScanStart(pHddCtx->hHal, pReqMsg);
4241 if (!HAL_STATUS_SUCCESS(status)) {
4242 hddLog(VOS_TRACE_LEVEL_ERROR,
4243 FL("sme_EXTScanStart failed(err=%d)"), status);
4244 vos_mem_free(pReqMsg);
4245 return -EINVAL;
4246 }
4247
Dino Myclee8843b32014-07-04 14:21:45 +05304248 vos_mem_free(pReqMsg);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304249 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304250 return 0;
4251
4252fail:
4253 vos_mem_free(pReqMsg);
4254 return -EINVAL;
4255}
4256
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304257static int wlan_hdd_cfg80211_extscan_start(struct wiphy *wiphy,
4258 struct wireless_dev *wdev,
4259 const void *data, int dataLen)
4260{
4261 int ret = 0;
4262
4263 vos_ssr_protect(__func__);
4264 ret = __wlan_hdd_cfg80211_extscan_start(wiphy, wdev, data, dataLen);
4265 vos_ssr_unprotect(__func__);
4266
4267 return ret;
4268}
4269
4270static int __wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304271 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304272 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304273{
Dino Myclee8843b32014-07-04 14:21:45 +05304274 tSirEXTScanStopReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304275 struct net_device *dev = wdev->netdev;
4276 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4277 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4278 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4279 eHalStatus status;
4280
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304281 ENTER();
4282
Dino Mycle6fb96c12014-06-10 11:52:40 +05304283 status = wlan_hdd_validate_context(pHddCtx);
4284 if (0 != status)
4285 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304286 return -EINVAL;
4287 }
Dino Myclee8843b32014-07-04 14:21:45 +05304288 /* check the EXTScan Capability */
4289 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4290 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4291 {
4292 hddLog(VOS_TRACE_LEVEL_ERROR,
4293 FL("EXTScan not enabled/supported by Firmware"));
4294 return -EINVAL;
4295 }
4296
Dino Mycle6fb96c12014-06-10 11:52:40 +05304297 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4298 data, dataLen,
4299 wlan_hdd_extscan_config_policy)) {
4300 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4301 return -EINVAL;
4302 }
4303
4304 /* Parse and fetch request Id */
4305 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4306 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4307 return -EINVAL;
4308 }
4309
Dino Myclee8843b32014-07-04 14:21:45 +05304310 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304311 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304312 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304313
Dino Myclee8843b32014-07-04 14:21:45 +05304314 reqMsg.sessionId = pAdapter->sessionId;
4315 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304316
Dino Myclee8843b32014-07-04 14:21:45 +05304317 status = sme_EXTScanStop(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304318 if (!HAL_STATUS_SUCCESS(status)) {
4319 hddLog(VOS_TRACE_LEVEL_ERROR,
4320 FL("sme_EXTScanStop failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304321 return -EINVAL;
4322 }
4323
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304324 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304325 return 0;
4326}
4327
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304328static int wlan_hdd_cfg80211_extscan_stop(struct wiphy *wiphy,
4329 struct wireless_dev *wdev,
4330 const void *data, int dataLen)
4331{
4332 int ret = 0;
4333
4334 vos_ssr_protect(__func__);
4335 ret = __wlan_hdd_cfg80211_extscan_stop(wiphy, wdev, data, dataLen);
4336 vos_ssr_unprotect(__func__);
4337
4338 return ret;
4339}
4340
4341static int __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
Dino Mycle6fb96c12014-06-10 11:52:40 +05304342 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304343 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304344{
Dino Myclee8843b32014-07-04 14:21:45 +05304345 tSirEXTScanResetBssidHotlistReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304346 struct net_device *dev = wdev->netdev;
4347 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4348 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4349 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4350 eHalStatus status;
4351
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304352 ENTER();
4353
Dino Mycle6fb96c12014-06-10 11:52:40 +05304354 status = wlan_hdd_validate_context(pHddCtx);
4355 if (0 != status)
4356 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304357 return -EINVAL;
4358 }
Dino Myclee8843b32014-07-04 14:21:45 +05304359 /* check the EXTScan Capability */
4360 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4361 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4362 {
4363 hddLog(VOS_TRACE_LEVEL_ERROR,
4364 FL("EXTScan not enabled/supported by Firmware"));
4365 return -EINVAL;
4366 }
4367
Dino Mycle6fb96c12014-06-10 11:52:40 +05304368 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4369 data, dataLen,
4370 wlan_hdd_extscan_config_policy)) {
4371 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4372 return -EINVAL;
4373 }
4374
4375 /* Parse and fetch request Id */
4376 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4377 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4378 return -EINVAL;
4379 }
4380
Dino Myclee8843b32014-07-04 14:21:45 +05304381 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304382 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304383 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304384
Dino Myclee8843b32014-07-04 14:21:45 +05304385 reqMsg.sessionId = pAdapter->sessionId;
4386 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304387
Dino Myclee8843b32014-07-04 14:21:45 +05304388 status = sme_ResetBssHotlist(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304389 if (!HAL_STATUS_SUCCESS(status)) {
4390 hddLog(VOS_TRACE_LEVEL_ERROR,
4391 FL("sme_ResetBssHotlist failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304392 return -EINVAL;
4393 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304394 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304395 return 0;
4396}
4397
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304398static int wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(struct wiphy *wiphy,
4399 struct wireless_dev *wdev,
4400 const void *data, int dataLen)
4401{
4402 int ret = 0;
4403
4404 vos_ssr_protect(__func__);
4405 ret = __wlan_hdd_cfg80211_extscan_reset_bssid_hotlist(wiphy, wdev, data, dataLen);
4406 vos_ssr_unprotect(__func__);
4407
4408 return ret;
4409}
4410
4411static int __wlan_hdd_cfg80211_extscan_reset_significant_change(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304412 struct wiphy *wiphy,
4413 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304414 const void *data, int dataLen)
Dino Mycle6fb96c12014-06-10 11:52:40 +05304415{
Dino Myclee8843b32014-07-04 14:21:45 +05304416 tSirEXTScanResetSignificantChangeReqParams reqMsg;
Dino Mycle6fb96c12014-06-10 11:52:40 +05304417 struct net_device *dev = wdev->netdev;
4418 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4419 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4420 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
4421 eHalStatus status;
4422
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304423 ENTER();
4424
Dino Mycle6fb96c12014-06-10 11:52:40 +05304425 status = wlan_hdd_validate_context(pHddCtx);
4426 if (0 != status)
4427 {
Dino Mycle6fb96c12014-06-10 11:52:40 +05304428 return -EINVAL;
4429 }
Dino Myclee8843b32014-07-04 14:21:45 +05304430 /* check the EXTScan Capability */
4431 if ( (TRUE != pHddCtx->cfg_ini->fEnableEXTScan) ||
4432 (TRUE != sme_IsFeatureSupportedByFW(EXTENDED_SCAN)))
4433 {
4434 hddLog(VOS_TRACE_LEVEL_ERROR,
4435 FL("EXTScan not enabled/supported by Firmware"));
4436 return -EINVAL;
4437 }
4438
Dino Mycle6fb96c12014-06-10 11:52:40 +05304439 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
4440 data, dataLen,
4441 wlan_hdd_extscan_config_policy)) {
4442 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4443 return -EINVAL;
4444 }
4445
4446 /* Parse and fetch request Id */
4447 if (!tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]) {
4448 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr request id failed"));
4449 return -EINVAL;
4450 }
4451
Dino Mycle6fb96c12014-06-10 11:52:40 +05304452
Dino Myclee8843b32014-07-04 14:21:45 +05304453 reqMsg.requestId = nla_get_u32(
Dino Mycle6fb96c12014-06-10 11:52:40 +05304454 tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_REQUEST_ID]);
Dino Myclee8843b32014-07-04 14:21:45 +05304455 hddLog(VOS_TRACE_LEVEL_INFO, FL("Req Id (%d)"), reqMsg.requestId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304456
Dino Myclee8843b32014-07-04 14:21:45 +05304457 reqMsg.sessionId = pAdapter->sessionId;
4458 hddLog(VOS_TRACE_LEVEL_INFO, FL("Session Id (%d)"), reqMsg.sessionId);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304459
Dino Myclee8843b32014-07-04 14:21:45 +05304460 status = sme_ResetSignificantChange(pHddCtx->hHal, &reqMsg);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304461 if (!HAL_STATUS_SUCCESS(status)) {
4462 hddLog(VOS_TRACE_LEVEL_ERROR,
4463 FL("sme_ResetSignificantChange failed(err=%d)"), status);
Dino Mycle6fb96c12014-06-10 11:52:40 +05304464 return -EINVAL;
4465 }
4466
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304467 EXIT();
Dino Mycle6fb96c12014-06-10 11:52:40 +05304468 return 0;
4469}
4470
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304471static int wlan_hdd_cfg80211_extscan_reset_significant_change(
4472 struct wiphy *wiphy,
4473 struct wireless_dev *wdev,
4474 const void *data, int dataLen)
4475{
4476 int ret = 0;
4477
4478 vos_ssr_protect(__func__);
4479 ret = __wlan_hdd_cfg80211_extscan_reset_significant_change(wiphy,
4480 wdev, data,
4481 dataLen);
4482 vos_ssr_unprotect(__func__);
4483
4484 return ret;
4485}
Dino Mycle6fb96c12014-06-10 11:52:40 +05304486#endif /* WLAN_FEATURE_EXTSCAN */
4487
Atul Mittal115287b2014-07-08 13:26:33 +05304488/*EXT TDLS*/
4489static const struct nla_policy
4490wlan_hdd_tdls_config_enable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX +1] =
4491{
4492 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4493 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL] = {.type = NLA_S32 },
4494 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS] =
4495 {.type = NLA_S32 },
4496 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS] = {.type = NLA_S32 },
4497 [QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS] = {.type = NLA_S32 },
4498
4499};
4500
4501static const struct nla_policy
4502wlan_hdd_tdls_config_disable_policy[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX +1] =
4503{
4504 [QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR] = {.type = NLA_UNSPEC },
4505
4506};
4507
4508static const struct nla_policy
4509wlan_hdd_tdls_config_state_change_policy[
4510 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAX +1] =
4511{
4512 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR] = {.type = NLA_UNSPEC },
4513 [QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE] = {.type = NLA_S32 },
4514 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304515 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL] = {.type = NLA_S32 },
4516 [QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS] =
4517 {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304518
4519};
4520
4521static const struct nla_policy
4522wlan_hdd_tdls_config_get_status_policy[
4523 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX +1] =
4524{
4525 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR] = {.type = NLA_UNSPEC },
4526 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE] = {.type = NLA_S32 },
4527 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON] = {.type = NLA_S32 },
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304528 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL] = {.type = NLA_S32 },
4529 [QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS]
4530 = {.type = NLA_S32 },
Atul Mittal115287b2014-07-08 13:26:33 +05304531
4532};
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304533
4534static const struct nla_policy
4535wlan_hdd_mac_config[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX+1] =
4536{
4537 [QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI] = {.type = NLA_UNSPEC },
4538};
4539
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304540static int __wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304541 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304542 const void *data,
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304543 int data_len)
4544{
4545
4546 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4547 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX + 1];
4548
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304549 ENTER();
4550
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304551 if (0 != wlan_hdd_validate_context(pHddCtx)){
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304552 return -EINVAL;
4553 }
4554 if (FALSE == pHddCtx->cfg_ini->enableMacSpoofing) {
4555 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN disabled in ini"));
4556 return -ENOTSUPP;
Siddharth Bhal76972212014-10-15 16:22:51 +05304557 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304558 if (TRUE != sme_IsFeatureSupportedByFW(MAC_SPOOFED_SCAN)){
4559 hddLog(VOS_TRACE_LEVEL_ERROR, FL("MAC_SPOOFED_SCAN not supported by FW"));
4560 return -ENOTSUPP;
4561 }
4562
4563 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI_MAX,
4564 data, data_len, wlan_hdd_mac_config)) {
4565 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4566 return -EINVAL;
4567 }
4568
4569 /* Parse and fetch mac address */
4570 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]) {
4571 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4572 return -EINVAL;
4573 }
4574
4575 memcpy(pHddCtx->spoofMacAddr.randomMacAddr.bytes, nla_data(
4576 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4577 VOS_MAC_ADDR_LAST_3_BYTES);
4578
Siddharth Bhal76972212014-10-15 16:22:51 +05304579 pHddCtx->spoofMacAddr.isEnabled = TRUE;
4580
4581 vos_trace_hex_dump( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, nla_data(
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304582 tb[QCA_WLAN_VENDOR_ATTR_SET_SCANNING_MAC_OUI]),
4583 VOS_MAC_ADDR_FIRST_3_BYTES);
Siddharth Bhal76972212014-10-15 16:22:51 +05304584 if ((pHddCtx->spoofMacAddr.randomMacAddr.bytes[0] == 0) &&
4585 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[1] == 0) &&
4586 (pHddCtx->spoofMacAddr.randomMacAddr.bytes[2] == 0))
4587 {
4588 hddLog(LOG1, FL("ZERO MAC OUI Recieved. Disabling Spoofing"));
4589 vos_mem_zero(pHddCtx->spoofMacAddr.randomMacAddr.bytes,
4590 VOS_MAC_ADDRESS_LEN);
4591 pHddCtx->spoofMacAddr.isEnabled = FALSE;
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304592 }
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304593
Siddharth Bhal76972212014-10-15 16:22:51 +05304594 if (VOS_STATUS_SUCCESS != hdd_processSpoofMacAddrRequest(pHddCtx))
4595 {
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304596 hddLog(LOGE, FL("Failed to send Spoof Mac Addr to FW"));
4597 }
4598
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304599 EXIT();
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05304600 return 0;
4601}
4602
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304603static int wlan_hdd_cfg80211_set_spoofed_mac_oui(struct wiphy *wiphy,
4604 struct wireless_dev *wdev,
4605 const void *data,
4606 int data_len)
4607{
4608 int ret = 0;
4609
4610 vos_ssr_protect(__func__);
4611 ret = __wlan_hdd_cfg80211_set_spoofed_mac_oui(wiphy, wdev, data, data_len);
4612 vos_ssr_unprotect(__func__);
4613
4614 return ret;
4615}
4616
4617static int __wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304618 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304619 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304620 int data_len)
4621{
4622 u8 peer[6] = {0};
4623 struct net_device *dev = wdev->netdev;
4624 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4625 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4626 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX + 1];
4627 eHalStatus ret;
4628 tANI_S32 state;
4629 tANI_S32 reason;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304630 tANI_S32 global_operating_class = 0;
4631 tANI_S32 channel = 0;
Atul Mittal115287b2014-07-08 13:26:33 +05304632 struct sk_buff *skb = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304633 int retVal;
4634
4635 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304636
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304637 if (!pAdapter) {
4638 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4639 return -EINVAL;
4640 }
4641
Atul Mittal115287b2014-07-08 13:26:33 +05304642 ret = wlan_hdd_validate_context(pHddCtx);
4643 if (0 != ret) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304644 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304645 return -EINVAL;
4646 }
4647 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304648 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304649 return -ENOTSUPP;
4650 }
4651 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAX,
4652 data, data_len,
4653 wlan_hdd_tdls_config_get_status_policy)) {
4654 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4655 return -EINVAL;
4656 }
4657
4658 /* Parse and fetch mac address */
4659 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]) {
4660 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4661 return -EINVAL;
4662 }
4663
4664 memcpy(peer, nla_data(
4665 tb[QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_MAC_ADDR]),
4666 sizeof(peer));
4667 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4668
Konamki, Sreelakshmiabb59ed2015-06-12 12:13:23 +05304669 wlan_hdd_tdls_get_status(pAdapter, peer, &state, &reason);
Atul Mittal115287b2014-07-08 13:26:33 +05304670
Atul Mittal115287b2014-07-08 13:26:33 +05304671 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304672 4 * sizeof(s32) +
Atul Mittal115287b2014-07-08 13:26:33 +05304673 NLMSG_HDRLEN);
4674
4675 if (!skb) {
4676 hddLog(VOS_TRACE_LEVEL_ERROR,
4677 FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
4678 return -EINVAL;
4679 }
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304680 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reason (%d) Status (%d) class (%d) channel (%d) peer" MAC_ADDRESS_STR),
Atul Mittal115287b2014-07-08 13:26:33 +05304681 reason,
4682 state,
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304683 global_operating_class,
4684 channel,
Atul Mittal115287b2014-07-08 13:26:33 +05304685 MAC_ADDR_ARRAY(peer));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304686 if (nla_put_s32(skb,
4687 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_STATE,
4688 state) ||
4689 nla_put_s32(skb,
4690 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_REASON,
4691 reason) ||
4692 nla_put_s32(skb,
4693 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_GLOBAL_OPERATING_CLASS,
4694 global_operating_class) ||
4695 nla_put_s32(skb,
4696 QCA_WLAN_VENDOR_ATTR_TDLS_GET_STATUS_CHANNEL,
4697 channel)) {
Atul Mittal115287b2014-07-08 13:26:33 +05304698
4699 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4700 goto nla_put_failure;
4701 }
4702
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304703 retVal = cfg80211_vendor_cmd_reply(skb);
4704 EXIT();
4705 return retVal;
Atul Mittal115287b2014-07-08 13:26:33 +05304706
4707nla_put_failure:
4708 kfree_skb(skb);
4709 return -EINVAL;
4710}
4711
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304712static int wlan_hdd_cfg80211_exttdls_get_status(struct wiphy *wiphy,
4713 struct wireless_dev *wdev,
4714 const void *data,
4715 int data_len)
4716{
4717 int ret = 0;
4718
4719 vos_ssr_protect(__func__);
4720 ret = __wlan_hdd_cfg80211_exttdls_get_status(wiphy, wdev, data, data_len);
4721 vos_ssr_unprotect(__func__);
4722
4723 return ret;
4724}
4725
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05304726static int wlan_hdd_cfg80211_exttdls_callback(
4727#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
4728 const tANI_U8* mac,
4729#else
4730 tANI_U8* mac,
4731#endif
Atul Mittal115287b2014-07-08 13:26:33 +05304732 tANI_S32 state,
4733 tANI_S32 reason,
4734 void *ctx)
4735{
4736 hdd_adapter_t* pAdapter = (hdd_adapter_t*)ctx;
Atul Mittal115287b2014-07-08 13:26:33 +05304737 struct sk_buff *skb = NULL;
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304738 tANI_S32 global_operating_class = 0;
4739 tANI_S32 channel = 0;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304740 hdd_context_t *pHddCtx;
Atul Mittal115287b2014-07-08 13:26:33 +05304741
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304742 ENTER();
4743
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304744 if (!pAdapter) {
4745 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4746 return -EINVAL;
4747 }
4748
4749 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +05304750 if (wlan_hdd_validate_context(pHddCtx)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304751 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304752 return -EINVAL;
4753 }
4754
4755 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304756 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304757 return -ENOTSUPP;
4758 }
Anand N Sunkad26ca6cc2015-07-29 09:54:52 +05304759 skb = cfg80211_vendor_event_alloc(pHddCtx->wiphy,
4760#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
4761 NULL,
4762#endif
Atul Mittal115287b2014-07-08 13:26:33 +05304763 EXTTDLS_EVENT_BUF_SIZE + NLMSG_HDRLEN,
4764 QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE_CHANGE_INDEX,
4765 GFP_KERNEL);
4766
4767 if (!skb) {
4768 hddLog(VOS_TRACE_LEVEL_ERROR,
4769 FL("cfg80211_vendor_event_alloc failed"));
4770 return -EINVAL;
4771 }
4772 hddLog(VOS_TRACE_LEVEL_INFO, FL("Entering "));
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304773 hddLog(VOS_TRACE_LEVEL_INFO, "Reason: (%d) Status: (%d) Class: (%d) Channel: (%d)",
4774 reason,
4775 state,
4776 global_operating_class,
4777 channel);
Atul Mittal115287b2014-07-08 13:26:33 +05304778 hddLog(VOS_TRACE_LEVEL_WARN, "tdls peer " MAC_ADDRESS_STR,
4779 MAC_ADDR_ARRAY(mac));
4780
Atul Mittal0a9f68d2014-10-16 15:26:38 +05304781 if (nla_put(skb,
4782 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_MAC_ADDR,
4783 VOS_MAC_ADDR_SIZE, mac) ||
4784 nla_put_s32(skb,
4785 QCA_WLAN_VENDOR_ATTR_TDLS_NEW_STATE,
4786 state) ||
4787 nla_put_s32(skb,
4788 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_REASON,
4789 reason) ||
4790 nla_put_s32(skb,
4791 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_CHANNEL,
4792 channel) ||
4793 nla_put_s32(skb,
4794 QCA_WLAN_VENDOR_ATTR_TDLS_STATE_GLOBAL_OPERATING_CLASS,
4795 global_operating_class)
4796 ) {
Atul Mittal115287b2014-07-08 13:26:33 +05304797 hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla put fail"));
4798 goto nla_put_failure;
4799 }
4800
4801 cfg80211_vendor_event(skb, GFP_KERNEL);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304802 EXIT();
Atul Mittal115287b2014-07-08 13:26:33 +05304803 return (0);
4804
4805nla_put_failure:
4806 kfree_skb(skb);
4807 return -EINVAL;
4808}
4809
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304810static int __wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304811 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304812 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304813 int data_len)
4814{
4815 u8 peer[6] = {0};
4816 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304817 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4818 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX + 1];
4819 eHalStatus status;
4820 tdls_req_params_t pReqMsg = {0};
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304821 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304822 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304823
4824 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304825
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304826 if (!dev) {
4827 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4828 return -EINVAL;
4829 }
4830
4831 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4832 if (!pAdapter) {
4833 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
4834 return -EINVAL;
4835 }
4836
Atul Mittal115287b2014-07-08 13:26:33 +05304837 status = wlan_hdd_validate_context(pHddCtx);
4838 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304839 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304840 return -EINVAL;
4841 }
4842 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304843 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304844 return -ENOTSUPP;
4845 }
4846 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX,
4847 data, data_len,
4848 wlan_hdd_tdls_config_enable_policy)) {
4849 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4850 return -EINVAL;
4851 }
4852
4853 /* Parse and fetch mac address */
4854 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]) {
4855 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4856 return -EINVAL;
4857 }
4858
4859 memcpy(peer, nla_data(
4860 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAC_ADDR]),
4861 sizeof(peer));
4862 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4863
4864 /* Parse and fetch channel */
4865 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]) {
4866 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr channel failed"));
4867 return -EINVAL;
4868 }
4869 pReqMsg.channel = nla_get_s32(
4870 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_CHANNEL]);
4871 hddLog(VOS_TRACE_LEVEL_INFO, FL("Channel Num (%d)"), pReqMsg.channel);
4872
4873 /* Parse and fetch global operating class */
4874 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]) {
4875 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr operating class failed"));
4876 return -EINVAL;
4877 }
4878 pReqMsg.global_operating_class = nla_get_s32(
4879 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_GLOBAL_OPERATING_CLASS]);
4880 hddLog(VOS_TRACE_LEVEL_INFO, FL("Operating class (%d)"),
4881 pReqMsg.global_operating_class);
4882
4883 /* Parse and fetch latency ms */
4884 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]) {
4885 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr latency failed"));
4886 return -EINVAL;
4887 }
4888 pReqMsg.max_latency_ms = nla_get_s32(
4889 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MAX_LATENCY_MS]);
4890 hddLog(VOS_TRACE_LEVEL_INFO, FL("Latency (%d)"),
4891 pReqMsg.max_latency_ms);
4892
4893 /* Parse and fetch required bandwidth kbps */
4894 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]) {
4895 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bandwidth failed"));
4896 return -EINVAL;
4897 }
4898
4899 pReqMsg.min_bandwidth_kbps = nla_get_s32(
4900 tb[QCA_WLAN_VENDOR_ATTR_TDLS_ENABLE_MIN_BANDWIDTH_KBPS]);
4901 hddLog(VOS_TRACE_LEVEL_INFO, FL("Bandwidth (%d)"),
4902 pReqMsg.min_bandwidth_kbps);
4903
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304904 ret = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
Atul Mittal115287b2014-07-08 13:26:33 +05304905 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +05304906 &pReqMsg,
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304907 wlan_hdd_cfg80211_exttdls_callback);
4908
4909 EXIT();
4910 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304911}
4912
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304913static int wlan_hdd_cfg80211_exttdls_enable(struct wiphy *wiphy,
4914 struct wireless_dev *wdev,
4915 const void *data,
4916 int data_len)
4917{
4918 int ret = 0;
4919
4920 vos_ssr_protect(__func__);
4921 ret = __wlan_hdd_cfg80211_exttdls_enable(wiphy, wdev, data, data_len);
4922 vos_ssr_unprotect(__func__);
4923
4924 return ret;
4925}
4926
4927static int __wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
Atul Mittal115287b2014-07-08 13:26:33 +05304928 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05304929 const void *data,
Atul Mittal115287b2014-07-08 13:26:33 +05304930 int data_len)
4931{
4932 u8 peer[6] = {0};
4933 struct net_device *dev = wdev->netdev;
Atul Mittal115287b2014-07-08 13:26:33 +05304934 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
4935 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX + 1];
4936 eHalStatus status;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304937 int ret;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304938 hdd_adapter_t *pAdapter;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304939
4940 ENTER();
Atul Mittal115287b2014-07-08 13:26:33 +05304941
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05304942 if (!dev) {
4943 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
4944 return -EINVAL;
4945 }
4946
4947 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
4948 if (!pAdapter) {
4949 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
4950 return -EINVAL;
4951 }
4952
Atul Mittal115287b2014-07-08 13:26:33 +05304953 status = wlan_hdd_validate_context(pHddCtx);
4954 if (0 != status) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304955 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid HDD context"));
Atul Mittal115287b2014-07-08 13:26:33 +05304956 return -EINVAL;
4957 }
4958 if (pHddCtx->cfg_ini->fTDLSExternalControl == FALSE) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05304959 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS external control is disabled"));
Atul Mittal115287b2014-07-08 13:26:33 +05304960 return -ENOTSUPP;
4961 }
4962 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAX,
4963 data, data_len,
4964 wlan_hdd_tdls_config_disable_policy)) {
4965 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
4966 return -EINVAL;
4967 }
4968 /* Parse and fetch mac address */
4969 if (!tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]) {
4970 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr mac addr failed"));
4971 return -EINVAL;
4972 }
4973
4974 memcpy(peer, nla_data(
4975 tb[QCA_WLAN_VENDOR_ATTR_TDLS_DISABLE_MAC_ADDR]),
4976 sizeof(peer));
4977 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(peer));
4978
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05304979 ret = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
4980
4981 EXIT();
4982 return ret;
Atul Mittal115287b2014-07-08 13:26:33 +05304983}
4984
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05304985static int wlan_hdd_cfg80211_exttdls_disable(struct wiphy *wiphy,
4986 struct wireless_dev *wdev,
4987 const void *data,
4988 int data_len)
4989{
4990 int ret = 0;
4991
4992 vos_ssr_protect(__func__);
4993 ret = __wlan_hdd_cfg80211_exttdls_disable(wiphy, wdev, data, data_len);
4994 vos_ssr_unprotect(__func__);
4995
4996 return ret;
4997}
4998
Dasari Srinivas7875a302014-09-26 17:50:57 +05304999static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305000__wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
Dasari Srinivas7875a302014-09-26 17:50:57 +05305001 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305002 const void *data, int data_len)
Dasari Srinivas7875a302014-09-26 17:50:57 +05305003{
5004 struct net_device *dev = wdev->netdev;
5005 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5006 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5007 struct sk_buff *skb = NULL;
5008 tANI_U32 fset = 0;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305009 int ret = 0;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305010
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305011 ENTER();
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305012
5013 ret = wlan_hdd_validate_context(pHddCtx);
5014 if (0 != ret)
5015 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305016 return ret;
5017 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305018 if (wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION)) {
5019 hddLog(LOG1, FL("Infra Station mode is supported by driver"));
5020 fset |= WIFI_FEATURE_INFRA;
5021 }
5022
5023 if (TRUE == hdd_is_5g_supported(pHddCtx)) {
5024 hddLog(LOG1, FL("INFRA_5G is supported by firmware"));
5025 fset |= WIFI_FEATURE_INFRA_5G;
5026 }
5027
5028#ifdef WLAN_FEATURE_P2P
5029 if ((wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) &&
5030 (wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_GO))) {
5031 hddLog(LOG1, FL("WiFi-Direct is supported by driver"));
5032 fset |= WIFI_FEATURE_P2P;
5033 }
5034#endif
5035
5036 /* Soft-AP is supported currently by default */
5037 fset |= WIFI_FEATURE_SOFT_AP;
5038
Kanchanapally, Vidyullatha683aed02015-03-24 16:58:38 +05305039 /* HOTSPOT is a supplicant feature, enable it by default */
5040 fset |= WIFI_FEATURE_HOTSPOT;
5041
Dasari Srinivas7875a302014-09-26 17:50:57 +05305042#ifdef WLAN_FEATURE_EXTSCAN
5043 if ((TRUE == pHddCtx->cfg_ini->fEnableEXTScan) &&
5044 sme_IsFeatureSupportedByFW(EXTENDED_SCAN)) {
5045 hddLog(LOG1, FL("EXTScan is supported by firmware"));
5046 fset |= WIFI_FEATURE_EXTSCAN;
5047 }
5048#endif
5049
Dasari Srinivas7875a302014-09-26 17:50:57 +05305050 if (sme_IsFeatureSupportedByFW(NAN)) {
5051 hddLog(LOG1, FL("NAN is supported by firmware"));
5052 fset |= WIFI_FEATURE_NAN;
5053 }
Dasari Srinivas7875a302014-09-26 17:50:57 +05305054
5055 /* D2D RTT is not supported currently by default */
5056 if (sme_IsFeatureSupportedByFW(RTT)) {
5057 hddLog(LOG1, FL("RTT is supported by firmware"));
5058 fset |= WIFI_FEATURE_D2AP_RTT;
5059 }
5060
5061#ifdef FEATURE_WLAN_BATCH_SCAN
5062 if (fset & WIFI_FEATURE_EXTSCAN) {
5063 hddLog(LOG1, FL("Batch scan is supported as extscan is supported"));
5064 fset &= ~WIFI_FEATURE_BATCH_SCAN;
5065 } else if (sme_IsFeatureSupportedByFW(BATCH_SCAN)) {
5066 hddLog(LOG1, FL("Batch scan is supported by firmware"));
5067 fset |= WIFI_FEATURE_BATCH_SCAN;
5068 }
5069#endif
5070
5071#ifdef FEATURE_WLAN_SCAN_PNO
5072 if (pHddCtx->cfg_ini->configPNOScanSupport &&
5073 (eHAL_STATUS_SUCCESS == wlan_hdd_is_pno_allowed(pAdapter))) {
5074 hddLog(LOG1, FL("PNO is supported by firmware"));
5075 fset |= WIFI_FEATURE_PNO;
5076 }
5077#endif
5078
5079 /* STA+STA is supported currently by default */
5080 fset |= WIFI_FEATURE_ADDITIONAL_STA;
5081
5082#ifdef FEATURE_WLAN_TDLS
5083 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSSupport) &&
5084 sme_IsFeatureSupportedByFW(TDLS)) {
5085 hddLog(LOG1, FL("TDLS is supported by firmware"));
5086 fset |= WIFI_FEATURE_TDLS;
5087 }
5088
5089 /* TDLS_OFFCHANNEL is not supported currently by default */
5090#endif
5091
5092#ifdef WLAN_AP_STA_CONCURRENCY
5093 /* AP+STA concurrency is supported currently by default */
5094 fset |= WIFI_FEATURE_AP_STA;
5095#endif
5096
5097 skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(fset) +
5098 NLMSG_HDRLEN);
5099
5100 if (!skb) {
5101 hddLog(LOGE, FL("cfg80211_vendor_cmd_alloc_reply_skb failed"));
5102 return -EINVAL;
5103 }
5104 hddLog(LOG1, FL("Supported Features : 0x%x"), fset);
5105
5106 if (nla_put_u32(skb, QCA_WLAN_VENDOR_ATTR_FEATURE_SET, fset)) {
5107 hddLog(LOGE, FL("nla put fail"));
5108 goto nla_put_failure;
5109 }
5110
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305111 ret = cfg80211_vendor_cmd_reply(skb);
5112 EXIT();
5113 return ret;
Dasari Srinivas7875a302014-09-26 17:50:57 +05305114
5115nla_put_failure:
5116 kfree_skb(skb);
5117 return -EINVAL;
5118}
5119
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305120static int
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305121wlan_hdd_cfg80211_get_supported_features(struct wiphy *wiphy,
5122 struct wireless_dev *wdev,
5123 const void *data, int data_len)
5124{
5125 int ret = 0;
5126
5127 vos_ssr_protect(__func__);
5128 ret = __wlan_hdd_cfg80211_get_supported_features(wiphy, wdev, data, data_len);
5129 vos_ssr_unprotect(__func__);
5130
5131 return ret;
5132}
5133
5134static int
5135__wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305136 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305137 const void *data, int data_len)
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305138{
5139 uint32_t feature_set_matrix[WLAN_HDD_MAX_FEATURE_SET] = {0};
5140 uint8_t i, feature_sets, max_feature_sets;
5141 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX + 1];
5142 struct sk_buff *reply_skb;
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305143 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5144 int ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305145
5146 ENTER();
5147
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305148 ret = wlan_hdd_validate_context(pHddCtx);
5149 if (0 != ret)
5150 {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305151 return ret;
5152 }
5153
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305154 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_MAX,
5155 data, data_len, NULL)) {
5156 hddLog(LOGE, FL("Invalid ATTR"));
5157 return -EINVAL;
5158 }
5159
5160 /* Parse and fetch max feature set */
5161 if (!tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]) {
5162 hddLog(LOGE, FL("Attr max feature set size failed"));
5163 return -EINVAL;
5164 }
5165 max_feature_sets = nla_get_u32(
5166 tb[QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_CONFIG_PARAM_SET_SIZE_MAX]);
5167 hddLog(LOG1, FL("Max feature set size (%d)"), max_feature_sets);
5168
5169 /* Fill feature combination matrix */
5170 feature_sets = 0;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305171 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5172 WIFI_FEATURE_P2P;
5173
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305174 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5175 WIFI_FEATURE_SOFT_AP;
5176
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305177 feature_set_matrix[feature_sets++] = WIFI_FEATURE_P2P |
5178 WIFI_FEATURE_SOFT_AP;
5179
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305180 feature_set_matrix[feature_sets++] = WIFI_FEATURE_INFRA |
5181 WIFI_FEATURE_SOFT_AP |
5182 WIFI_FEATURE_P2P;
5183
5184 /* Add more feature combinations here */
5185
5186 feature_sets = VOS_MIN(feature_sets, max_feature_sets);
5187 hddLog(LOG1, FL("Number of feature sets (%d)"), feature_sets);
5188 hddLog(LOG1, "Feature set matrix");
5189 for (i = 0; i < feature_sets; i++)
5190 hddLog(LOG1, "[%d] 0x%02X", i, feature_set_matrix[i]);
5191
5192 reply_skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, sizeof(u32) +
5193 sizeof(u32) * feature_sets +
5194 NLMSG_HDRLEN);
5195
5196 if (reply_skb) {
5197 if (nla_put_u32(reply_skb,
5198 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET_SIZE,
5199 feature_sets) ||
5200 nla_put(reply_skb,
5201 QCA_WLAN_VENDOR_ATTR_GET_CONCURRENCY_MATRIX_RESULTS_SET,
5202 sizeof(u32) * feature_sets, feature_set_matrix)) {
5203 hddLog(LOGE, FL("nla put fail"));
5204 kfree_skb(reply_skb);
5205 return -EINVAL;
5206 }
5207
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305208 ret = cfg80211_vendor_cmd_reply(reply_skb);
5209 EXIT();
5210 return ret;
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305211 }
5212 hddLog(LOGE, FL("Feature set matrix: buffer alloc fail"));
5213 return -ENOMEM;
5214
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305215}
5216
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305217static int
5218wlan_hdd_cfg80211_get_concurrency_matrix(struct wiphy *wiphy,
5219 struct wireless_dev *wdev,
5220 const void *data, int data_len)
5221{
5222 int ret = 0;
5223
5224 vos_ssr_protect(__func__);
5225 ret = __wlan_hdd_cfg80211_get_concurrency_matrix(wiphy, wdev, data,
5226 data_len);
5227 vos_ssr_unprotect(__func__);
5228
5229 return ret;
5230}
5231
Agarwal Ashish738843c2014-09-25 12:27:56 +05305232static const struct nla_policy
5233wlan_hdd_set_no_dfs_flag_config_policy[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX
5234 +1] =
5235{
5236 [QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG] = {.type = NLA_U32 },
5237};
5238
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305239static int __wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305240 struct wireless_dev *wdev,
Jeff Johnson393c2702014-12-16 11:09:35 +05305241 const void *data,
Agarwal Ashish738843c2014-09-25 12:27:56 +05305242 int data_len)
5243{
5244 struct net_device *dev = wdev->netdev;
5245 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
5246 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
5247 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5248 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX + 1];
5249 eHalStatus status;
5250 u32 dfsFlag = 0;
5251
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305252 ENTER();
5253
Agarwal Ashish738843c2014-09-25 12:27:56 +05305254 status = wlan_hdd_validate_context(pHddCtx);
5255 if (0 != status) {
Agarwal Ashish738843c2014-09-25 12:27:56 +05305256 return -EINVAL;
5257 }
5258 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG_MAX,
5259 data, data_len,
5260 wlan_hdd_set_no_dfs_flag_config_policy)) {
5261 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5262 return -EINVAL;
5263 }
5264
5265 /* Parse and fetch required bandwidth kbps */
5266 if (!tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]) {
5267 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr dfs flag failed"));
5268 return -EINVAL;
5269 }
5270
5271 dfsFlag = nla_get_u32(
5272 tb[QCA_WLAN_VENDOR_ATTR_SET_NO_DFS_FLAG]);
5273 hddLog(VOS_TRACE_LEVEL_INFO, FL(" DFS flag (%d)"),
5274 dfsFlag);
5275
5276 pHddCtx->disable_dfs_flag = dfsFlag;
5277
5278 sme_disable_dfs_channel(hHal, dfsFlag);
5279 sme_FilterScanResults(hHal, pAdapter->sessionId);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305280
5281 EXIT();
Agarwal Ashish738843c2014-09-25 12:27:56 +05305282 return 0;
5283}
Atul Mittal115287b2014-07-08 13:26:33 +05305284
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305285static int wlan_hdd_cfg80211_disable_dfs_channels(struct wiphy *wiphy,
5286 struct wireless_dev *wdev,
5287 const void *data,
5288 int data_len)
5289{
5290 int ret = 0;
5291
5292 vos_ssr_protect(__func__);
5293 ret = __wlan_hdd_cfg80211_disable_dfs_channels(wiphy, wdev, data, data_len);
5294 vos_ssr_unprotect(__func__);
5295
5296 return ret;
5297
5298}
5299
Mukul Sharma2a271632014-10-13 14:59:01 +05305300const struct
5301nla_policy qca_wlan_vendor_attr[QCA_WLAN_VENDOR_ATTR_MAX+1] =
5302{
5303 [QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY] = { .type = NLA_U32 },
5304 [QCA_WLAN_VENDOR_ATTR_MAC_ADDR] = { .type = NLA_UNSPEC },
5305};
5306
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305307static int __wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
Jeff Johnson393c2702014-12-16 11:09:35 +05305308 struct wireless_dev *wdev, const void *data, int data_len)
Mukul Sharma2a271632014-10-13 14:59:01 +05305309{
5310
5311 u8 bssid[6] = {0};
5312 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5313 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5314 eHalStatus status = eHAL_STATUS_SUCCESS;
5315 v_U32_t isFwrRoamEnabled = FALSE;
5316 int ret;
5317
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305318 ENTER();
5319
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305320 ret = wlan_hdd_validate_context(pHddCtx);
5321 if (0 != ret) {
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305322 return ret;
Mukul Sharma2a271632014-10-13 14:59:01 +05305323 }
5324
5325 ret = nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX,
5326 data, data_len,
5327 qca_wlan_vendor_attr);
5328 if (ret){
5329 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Invalid ATTR"));
5330 return -EINVAL;
5331 }
5332
5333 /* Parse and fetch Enable flag */
5334 if (!tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]) {
5335 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr enable failed"));
5336 return -EINVAL;
5337 }
5338
5339 isFwrRoamEnabled = nla_get_u32(
5340 tb[QCA_WLAN_VENDOR_ATTR_ROAMING_POLICY]);
5341
5342 hddLog(VOS_TRACE_LEVEL_INFO, FL("isFwrRoamEnabled (%d)"), isFwrRoamEnabled);
5343
5344 /* Parse and fetch bssid */
5345 if (!tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]) {
5346 hddLog(VOS_TRACE_LEVEL_ERROR, FL("attr bss id failed"));
5347 return -EINVAL;
5348 }
5349
5350 memcpy(bssid, nla_data(
5351 tb[QCA_WLAN_VENDOR_ATTR_MAC_ADDR]),
5352 sizeof(bssid));
5353 hddLog(VOS_TRACE_LEVEL_INFO, FL(MAC_ADDRESS_STR),MAC_ADDR_ARRAY(bssid));
5354
5355 //Update roaming
5356 status = sme_ConfigFwrRoaming((tHalHandle)(pHddCtx->hHal), isFwrRoamEnabled);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05305357 EXIT();
Mukul Sharma2a271632014-10-13 14:59:01 +05305358 return status;
5359}
5360
Mahesh A Saptasagare5440c72015-01-28 21:21:07 +05305361static int wlan_hdd_cfg80211_firmware_roaming(struct wiphy *wiphy,
5362 struct wireless_dev *wdev, const void *data, int data_len)
5363{
5364 int ret = 0;
5365
5366 vos_ssr_protect(__func__);
5367 ret = __wlan_hdd_cfg80211_firmware_roaming(wiphy, wdev, data, data_len);
5368 vos_ssr_unprotect(__func__);
5369
5370 return ret;
5371}
5372
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305373/**
5374 * __wlan_hdd_cfg80211_setband() - set band
5375 * @wiphy: Pointer to wireless phy
5376 * @wdev: Pointer to wireless device
5377 * @data: Pointer to data
5378 * @data_len: Data length
5379 *
5380 * Return: 0 on success, negative errno on failure
5381 */
5382static int
5383__wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
5384 struct wireless_dev *wdev,
5385 const void *data,
5386 int data_len)
5387{
5388 struct net_device *dev = wdev->netdev;
5389 hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
5390 struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_MAX + 1];
5391 int ret;
5392 static const struct nla_policy policy[QCA_WLAN_VENDOR_ATTR_MAX + 1]
5393 = {[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE] = { .type = NLA_U32 }};
5394
5395 ENTER();
5396
5397 ret = wlan_hdd_validate_context(hdd_ctx);
5398 if (0 != ret) {
5399 hddLog(LOGE, FL("HDD context is not valid"));
5400 return ret;
5401 }
5402
5403 if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_MAX, data, data_len,
5404 policy)) {
5405 hddLog(LOGE, FL("Invalid ATTR"));
5406 return -EINVAL;
5407 }
5408
5409 if (!tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]) {
5410 hddLog(LOGE, FL("attr QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE failed"));
5411 return -EINVAL;
5412 }
5413
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05305414 hdd_ctx->isSetBandByNL = TRUE;
5415 ret = hdd_setBand(dev,
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305416 nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_SETBAND_VALUE]));
Hanumantha Reddy Pothula1347e432015-08-05 09:53:44 +05305417 hdd_ctx->isSetBandByNL = FALSE;
5418
5419 EXIT();
5420 return ret;
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305421}
5422
5423/**
5424 * wlan_hdd_cfg80211_setband() - Wrapper to offload packets
5425 * @wiphy: wiphy structure pointer
5426 * @wdev: Wireless device structure pointer
5427 * @data: Pointer to the data received
5428 * @data_len: Length of @data
5429 *
5430 * Return: 0 on success; errno on failure
5431 */
5432static int wlan_hdd_cfg80211_setband(struct wiphy *wiphy,
5433 struct wireless_dev *wdev,
5434 const void *data,
5435 int data_len)
5436{
5437 int ret = 0;
5438
5439 vos_ssr_protect(__func__);
5440 ret = __wlan_hdd_cfg80211_setband(wiphy,
5441 wdev, data, data_len);
5442 vos_ssr_unprotect(__func__);
5443
5444 return ret;
5445}
5446
Sunil Duttc69bccb2014-05-26 21:30:20 +05305447const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
5448{
Mukul Sharma2a271632014-10-13 14:59:01 +05305449 {
5450 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5451 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ROAMING,
5452 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5453 WIPHY_VENDOR_CMD_NEED_NETDEV |
5454 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305455 .doit = wlan_hdd_cfg80211_firmware_roaming
Mukul Sharma2a271632014-10-13 14:59:01 +05305456 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05305457
5458 {
5459 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5460 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN,
5461 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5462 WIPHY_VENDOR_CMD_NEED_NETDEV |
5463 WIPHY_VENDOR_CMD_NEED_RUNNING,
5464 .doit = wlan_hdd_cfg80211_nan_request
5465 },
5466
Sunil Duttc69bccb2014-05-26 21:30:20 +05305467#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5468 {
5469 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5470 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR,
5471 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5472 WIPHY_VENDOR_CMD_NEED_NETDEV |
5473 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305474 .doit = wlan_hdd_cfg80211_ll_stats_clear
Sunil Duttc69bccb2014-05-26 21:30:20 +05305475 },
5476
5477 {
5478 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5479 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET,
5480 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5481 WIPHY_VENDOR_CMD_NEED_NETDEV |
5482 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305483 .doit = wlan_hdd_cfg80211_ll_stats_set
Sunil Duttc69bccb2014-05-26 21:30:20 +05305484 },
5485
5486 {
5487 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5488 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET,
5489 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5490 WIPHY_VENDOR_CMD_NEED_NETDEV |
5491 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305492 .doit = wlan_hdd_cfg80211_ll_stats_get
Dino Mycle6fb96c12014-06-10 11:52:40 +05305493 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305494#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305495#ifdef WLAN_FEATURE_EXTSCAN
5496 {
5497 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5498 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START,
5499 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5500 WIPHY_VENDOR_CMD_NEED_NETDEV |
5501 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305502 .doit = wlan_hdd_cfg80211_extscan_start
Dino Mycle6fb96c12014-06-10 11:52:40 +05305503 },
5504 {
5505 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5506 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP,
5507 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5508 WIPHY_VENDOR_CMD_NEED_NETDEV |
5509 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305510 .doit = wlan_hdd_cfg80211_extscan_stop
Dino Mycle6fb96c12014-06-10 11:52:40 +05305511 },
5512 {
5513 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5514 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_VALID_CHANNELS,
5515 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5516 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305517 .doit = wlan_hdd_cfg80211_extscan_get_valid_channels
Dino Mycle6fb96c12014-06-10 11:52:40 +05305518 },
5519 {
5520 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5521 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES,
5522 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5523 WIPHY_VENDOR_CMD_NEED_NETDEV |
5524 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305525 .doit = wlan_hdd_cfg80211_extscan_get_capabilities
Dino Mycle6fb96c12014-06-10 11:52:40 +05305526 },
5527 {
5528 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5529 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS,
5530 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5531 WIPHY_VENDOR_CMD_NEED_NETDEV |
5532 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305533 .doit = wlan_hdd_cfg80211_extscan_get_cached_results
Dino Mycle6fb96c12014-06-10 11:52:40 +05305534 },
5535 {
5536 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5537 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST,
5538 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5539 WIPHY_VENDOR_CMD_NEED_NETDEV |
5540 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305541 .doit = wlan_hdd_cfg80211_extscan_set_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305542 },
5543 {
5544 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5545 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST,
5546 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5547 WIPHY_VENDOR_CMD_NEED_NETDEV |
5548 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305549 .doit = wlan_hdd_cfg80211_extscan_reset_bssid_hotlist
Dino Mycle6fb96c12014-06-10 11:52:40 +05305550 },
5551 {
5552 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5553 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE,
5554 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5555 WIPHY_VENDOR_CMD_NEED_NETDEV |
5556 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305557 .doit = wlan_hdd_cfg80211_extscan_set_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305558 },
5559 {
5560 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5561 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE,
5562 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5563 WIPHY_VENDOR_CMD_NEED_NETDEV |
5564 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305565 .doit = wlan_hdd_cfg80211_extscan_reset_significant_change
Dino Mycle6fb96c12014-06-10 11:52:40 +05305566 },
5567#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305568/*EXT TDLS*/
5569 {
5570 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5571 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_ENABLE,
5572 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5573 WIPHY_VENDOR_CMD_NEED_NETDEV |
5574 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305575 .doit = wlan_hdd_cfg80211_exttdls_enable
Atul Mittal115287b2014-07-08 13:26:33 +05305576 },
5577 {
5578 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5579 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_DISABLE,
5580 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5581 WIPHY_VENDOR_CMD_NEED_NETDEV |
5582 WIPHY_VENDOR_CMD_NEED_RUNNING,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305583 .doit = wlan_hdd_cfg80211_exttdls_disable
Atul Mittal115287b2014-07-08 13:26:33 +05305584 },
5585 {
5586 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5587 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_GET_STATUS,
5588 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5589 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305590 .doit = wlan_hdd_cfg80211_exttdls_get_status
Atul Mittal115287b2014-07-08 13:26:33 +05305591 },
Dasari Srinivas7875a302014-09-26 17:50:57 +05305592 {
5593 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5594 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_SUPPORTED_FEATURES,
5595 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5596 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305597 .doit = wlan_hdd_cfg80211_get_supported_features
Dasari Srinivas7875a302014-09-26 17:50:57 +05305598 },
Agarwal Ashish738843c2014-09-25 12:27:56 +05305599 {
5600 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5601 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_NO_DFS_FLAG,
5602 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5603 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305604 .doit = wlan_hdd_cfg80211_disable_dfs_channels
Agarwal Ashish738843c2014-09-25 12:27:56 +05305605 },
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305606 {
5607 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5608 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_MAC_OUI,
5609 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5610 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305611 .doit = wlan_hdd_cfg80211_set_spoofed_mac_oui
Siddharth Bhala3a5cb42014-09-29 21:13:13 +05305612 },
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305613 {
5614 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5615 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_GET_CONCURRENCY_MATRIX,
5616 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5617 WIPHY_VENDOR_CMD_NEED_NETDEV,
Edhar, Mahesh Kumar59129f52015-01-14 14:26:04 +05305618 .doit = wlan_hdd_cfg80211_get_concurrency_matrix
Dasari Srinivase18b2cf2014-10-28 17:09:42 +05305619 },
Srinivas Dasari41d97c92015-07-29 13:09:39 +05305620 {
5621 .info.vendor_id = QCA_NL80211_VENDOR_ID,
5622 .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SETBAND,
5623 .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
5624 WIPHY_VENDOR_CMD_NEED_NETDEV |
5625 WIPHY_VENDOR_CMD_NEED_RUNNING,
5626 .doit = wlan_hdd_cfg80211_setband
5627 }
Sunil Duttc69bccb2014-05-26 21:30:20 +05305628};
5629
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005630/* vendor specific events */
Sunil Duttc69bccb2014-05-26 21:30:20 +05305631static const
5632struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] =
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005633{
5634#ifdef FEATURE_WLAN_CH_AVOID
5635 {
Sunil Duttc69bccb2014-05-26 21:30:20 +05305636 .vendor_id = QCA_NL80211_VENDOR_ID,
5637 .subcmd = QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005638 },
Sunil Duttc69bccb2014-05-26 21:30:20 +05305639#endif /* FEATURE_WLAN_CH_AVOID Index = 0*/
5640#ifdef WLAN_FEATURE_LINK_LAYER_STATS
5641 {
5642 /* Index = 1*/
5643 .vendor_id = QCA_NL80211_VENDOR_ID,
5644 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET
5645 },
5646 {
5647 /* Index = 2*/
5648 .vendor_id = QCA_NL80211_VENDOR_ID,
5649 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET
5650 },
5651 {
5652 /* Index = 3*/
5653 .vendor_id = QCA_NL80211_VENDOR_ID,
5654 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR
5655 },
5656 {
5657 /* Index = 4*/
5658 .vendor_id = QCA_NL80211_VENDOR_ID,
5659 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS
5660 },
5661 {
5662 /* Index = 5*/
5663 .vendor_id = QCA_NL80211_VENDOR_ID,
5664 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS
5665 },
5666 {
5667 /* Index = 6*/
5668 .vendor_id = QCA_NL80211_VENDOR_ID,
5669 .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS
5670 },
5671#endif /* WLAN_FEATURE_LINK_LAYER_STATS */
Dino Mycle6fb96c12014-06-10 11:52:40 +05305672#ifdef WLAN_FEATURE_EXTSCAN
5673 {
5674 .vendor_id = QCA_NL80211_VENDOR_ID,
5675 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START
5676 },
5677 {
5678 .vendor_id = QCA_NL80211_VENDOR_ID,
5679 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP
5680 },
5681 {
5682 .vendor_id = QCA_NL80211_VENDOR_ID,
5683 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES
5684 },
5685 {
5686 .vendor_id = QCA_NL80211_VENDOR_ID,
5687 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS
5688 },
5689 {
5690 .vendor_id = QCA_NL80211_VENDOR_ID,
5691 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE
5692 },
5693 {
5694 .vendor_id = QCA_NL80211_VENDOR_ID,
5695 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT
5696 },
5697 {
5698 .vendor_id = QCA_NL80211_VENDOR_ID,
5699 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT
5700 },
5701 {
5702 .vendor_id = QCA_NL80211_VENDOR_ID,
5703 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND
5704 },
5705 {
5706 .vendor_id = QCA_NL80211_VENDOR_ID,
5707 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST
5708 },
5709 {
5710 .vendor_id = QCA_NL80211_VENDOR_ID,
5711 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST
5712 },
5713 {
5714 .vendor_id = QCA_NL80211_VENDOR_ID,
5715 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE
5716 },
5717 {
5718 .vendor_id = QCA_NL80211_VENDOR_ID,
5719 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE
5720 },
5721 {
5722 .vendor_id = QCA_NL80211_VENDOR_ID,
5723 .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE
5724 },
5725#endif /* WLAN_FEATURE_EXTSCAN */
Atul Mittal115287b2014-07-08 13:26:33 +05305726/*EXT TDLS*/
5727 {
5728 .vendor_id = QCA_NL80211_VENDOR_ID,
5729 .subcmd = QCA_NL80211_VENDOR_SUBCMD_TDLS_STATE
5730 },
Srinivas Dasari030bad32015-02-18 23:23:54 +05305731
5732 {
5733 .vendor_id = QCA_NL80211_VENDOR_ID,
5734 .subcmd = QCA_NL80211_VENDOR_SUBCMD_NAN
5735 },
5736
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08005737};
5738
Jeff Johnson295189b2012-06-20 16:38:30 -07005739/*
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305740 * FUNCTION: wlan_hdd_cfg80211_wiphy_alloc
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305741 * This function is called by hdd_wlan_startup()
5742 * during initialization.
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305743 * This function is used to allocate wiphy structure.
Jeff Johnson295189b2012-06-20 16:38:30 -07005744 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305745struct wiphy *wlan_hdd_cfg80211_wiphy_alloc(int priv_size)
Jeff Johnson295189b2012-06-20 16:38:30 -07005746{
5747 struct wiphy *wiphy;
5748 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305749 /*
5750 * Create wiphy device
Jeff Johnson295189b2012-06-20 16:38:30 -07005751 */
5752 wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size);
5753
5754 if (!wiphy)
5755 {
5756 /* Print error and jump into err label and free the memory */
5757 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wiphy init failed", __func__);
5758 return NULL;
5759 }
5760
Sunil Duttc69bccb2014-05-26 21:30:20 +05305761
Jeff Johnson295189b2012-06-20 16:38:30 -07005762 return wiphy;
5763}
5764
5765/*
5766 * FUNCTION: wlan_hdd_cfg80211_update_band
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305767 * This function is called from the supplicant through a
Jeff Johnson295189b2012-06-20 16:38:30 -07005768 * private ioctl to change the band value
5769 */
5770int wlan_hdd_cfg80211_update_band(struct wiphy *wiphy, eCsrBand eBand)
5771{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305772 int i, j;
5773 eNVChannelEnabledType channelEnabledState;
5774
Jeff Johnsone7245742012-09-05 17:12:55 -07005775 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05305776
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305777 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
Jeff Johnson295189b2012-06-20 16:38:30 -07005778 {
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305779
5780 if (NULL == wiphy->bands[i])
5781 {
5782 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5783 __func__, i);
5784 continue;
5785 }
5786
5787 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5788 {
5789 struct ieee80211_supported_band *band = wiphy->bands[i];
5790
5791 channelEnabledState = vos_nv_getChannelEnabledState(
5792 band->channels[j].hw_value);
5793
5794 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == eBand) // 5G only
5795 {
Abhishek Singh678227a2014-11-04 10:52:38 +05305796 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305797 continue;
5798 }
5799 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == eBand) // 2G only
5800 {
5801 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5802 continue;
5803 }
5804
5805 if (NV_CHANNEL_DISABLE == channelEnabledState ||
5806 NV_CHANNEL_INVALID == channelEnabledState)
5807 {
5808 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5809 }
5810 else if (NV_CHANNEL_DFS == channelEnabledState)
5811 {
5812 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5813 band->channels[j].flags |= IEEE80211_CHAN_RADAR;
5814 }
5815 else
5816 {
5817 band->channels[j].flags &= ~(IEEE80211_CHAN_DISABLED
5818 |IEEE80211_CHAN_RADAR);
5819 }
5820 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005821 }
5822 return 0;
5823}
5824/*
5825 * FUNCTION: wlan_hdd_cfg80211_init
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305826 * This function is called by hdd_wlan_startup()
5827 * during initialization.
Jeff Johnson295189b2012-06-20 16:38:30 -07005828 * This function is used to initialize and register wiphy structure.
5829 */
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05305830int wlan_hdd_cfg80211_init(struct device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07005831 struct wiphy *wiphy,
5832 hdd_config_t *pCfg
5833 )
5834{
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305835 int i, j;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305836 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
5837
Jeff Johnsone7245742012-09-05 17:12:55 -07005838 ENTER();
5839
Jeff Johnson295189b2012-06-20 16:38:30 -07005840 /* Now bind the underlying wlan device with wiphy */
5841 set_wiphy_dev(wiphy, dev);
5842
5843 wiphy->mgmt_stypes = wlan_hdd_txrx_stypes;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005844
Kiet Lam6c583332013-10-14 05:37:09 +05305845#ifndef CONFIG_ENABLE_LINUX_REG
Amar Singhal0a402232013-10-11 20:57:16 -07005846 /* the flag for the other case would be initialzed in
5847 vos_init_wiphy_from_nv_bin */
Amar Singhal0a402232013-10-11 20:57:16 -07005848 wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
Kiet Lam6c583332013-10-14 05:37:09 +05305849#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005850
Amar Singhalfddc28c2013-09-05 13:03:40 -07005851 /* This will disable updating of NL channels from passive to
5852 * active if a beacon is received on passive channel. */
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05305853#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
5854 wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
5855#else
Amar Singhalfddc28c2013-09-05 13:03:40 -07005856 wiphy->flags |= WIPHY_FLAG_DISABLE_BEACON_HINTS;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05305857#endif
Amar Singhalfddc28c2013-09-05 13:03:40 -07005858
Amar Singhala49cbc52013-10-08 18:37:44 -07005859
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005860#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -07005861 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME
5862 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD
5863 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
Jeff Johnsone7245742012-09-05 17:12:55 -07005864 | WIPHY_FLAG_OFFCHAN_TX;
Anand N Sunkade9adb1b2015-07-29 09:56:45 +05305865#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,14,0))
5866 wiphy->regulatory_flags = REGULATORY_COUNTRY_IE_IGNORE;
5867#else
5868 wiphy->country_ie_pref = NL80211_COUNTRY_IE_IGNORE_CORE;
5869#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005870#endif
Amar Singhala49cbc52013-10-08 18:37:44 -07005871
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005872#if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR)
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005873 if (pCfg->isFastTransitionEnabled
James Zmuda77fb5ae2013-01-29 08:00:17 -08005874#ifdef FEATURE_WLAN_LFR
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005875 || pCfg->isFastRoamIniFeatureEnabled
5876#endif
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08005877#ifdef FEATURE_WLAN_ESE
5878 || pCfg->isEseIniFeatureEnabled
Srinivas Girigowda640728a2013-03-28 12:21:54 -07005879#endif
5880 )
5881 {
5882 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5883 }
James Zmuda77fb5ae2013-01-29 08:00:17 -08005884#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005885#ifdef FEATURE_WLAN_TDLS
5886 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS
5887 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP;
5888#endif
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305889#ifdef FEATURE_WLAN_SCAN_PNO
Hardik Kantilal Patel3dfd8792013-11-13 20:34:57 +05305890 if (pCfg->configPNOScanSupport)
5891 {
5892 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5893 wiphy->max_sched_scan_ssids = SIR_PNO_MAX_SUPP_NETWORKS;
5894 wiphy->max_match_sets = SIR_PNO_MAX_SUPP_NETWORKS;
5895 wiphy->max_sched_scan_ie_len = SIR_MAC_MAX_IE_LENGTH;
5896 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +05305897#endif/*FEATURE_WLAN_SCAN_PNO*/
Mohit Khanna698ba2a2012-12-04 15:08:18 -08005898
Abhishek Singh10d85972015-04-17 10:27:23 +05305899#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5900 wiphy->features |= NL80211_FEATURE_HT_IBSS;
5901#endif
5902
Amar Singhalfddc28c2013-09-05 13:03:40 -07005903#ifdef CONFIG_ENABLE_LINUX_REG
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005904 /* even with WIPHY_FLAG_CUSTOM_REGULATORY,
5905 driver can still register regulatory callback and
Amar Singhalfddc28c2013-09-05 13:03:40 -07005906 it will get regulatory settings in wiphy->band[], but
Madan Mohan Koyyalamudic3a240c2012-09-28 15:34:08 -07005907 driver need to determine what to do with both
5908 regulatory settings */
Amar Singhalfddc28c2013-09-05 13:03:40 -07005909
5910 wiphy->reg_notifier = wlan_hdd_linux_reg_notifier;
Amar Singhala49cbc52013-10-08 18:37:44 -07005911#else
5912 wiphy->reg_notifier = wlan_hdd_crda_reg_notifier;
Amar Singhalfddc28c2013-09-05 13:03:40 -07005913#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07005914
Gopichand Nakkala747461f2013-04-24 19:24:45 +05305915 wiphy->max_scan_ssids = MAX_SCAN_SSID;
5916
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +05305917 wiphy->max_scan_ie_len = SIR_MAC_MAX_ADD_IE_LENGTH;
Jeff Johnson295189b2012-06-20 16:38:30 -07005918
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05305919 wiphy->max_acl_mac_addrs = MAX_ACL_MAC_ADDRESS;
5920
Jeff Johnson295189b2012-06-20 16:38:30 -07005921 /* Supports STATION & AD-HOC modes right now */
Bhargav Shah0d2e3e52015-07-24 16:51:01 +05305922 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
5923 | BIT(NL80211_IFTYPE_ADHOC)
5924 | BIT(NL80211_IFTYPE_P2P_CLIENT)
5925 | BIT(NL80211_IFTYPE_P2P_GO)
5926 | BIT(NL80211_IFTYPE_AP);
5927
5928 if (VOS_MONITOR_MODE == hdd_get_conparam())
5929 {
5930 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
5931 }
Jeff Johnson295189b2012-06-20 16:38:30 -07005932
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305933 if( pCfg->advertiseConcurrentOperation )
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005934 {
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305935#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
5936 if( pCfg->enableMCC )
5937 {
5938 /* Currently, supports up to two channels */
5939 wlan_hdd_iface_combination.num_different_channels = 2;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005940
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305941 if( !pCfg->allowMCCGODiffBI )
5942 wlan_hdd_iface_combination.beacon_int_infra_match = true;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005943
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305944 }
5945 wiphy->iface_combinations = &wlan_hdd_iface_combination;
5946 wiphy->n_iface_combinations = 1;
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005947#endif
Rashmi Ramannabd3feb72014-02-25 16:14:48 +05305948 }
Sudhir Sattayappa Kohalli278eee52013-01-16 17:35:13 -08005949
Jeff Johnson295189b2012-06-20 16:38:30 -07005950 /* Before registering we need to update the ht capabilitied based
5951 * on ini values*/
5952 if( !pCfg->ShortGI20MhzEnable )
5953 {
5954 wlan_hdd_band_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5955 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5956 wlan_hdd_band_p2p_2_4_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_20;
5957 }
5958
5959 if( !pCfg->ShortGI40MhzEnable )
5960 {
5961 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40;
5962 }
5963
5964 if( !pCfg->nChannelBondingMode5GHz )
5965 {
5966 wlan_hdd_band_5_GHZ.ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5967 }
5968
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305969 wiphy->bands[IEEE80211_BAND_2GHZ] = &wlan_hdd_band_2_4_GHZ;
Vinay Krishna Erannafacf5e22014-02-24 13:16:25 +05305970 if (true == hdd_is_5g_supported(pHddCtx))
5971 {
5972 wiphy->bands[IEEE80211_BAND_5GHZ] = &wlan_hdd_band_5_GHZ;
5973 }
Gopichand Nakkala1f7a64f2013-04-01 18:37:17 +05305974
5975 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
5976 {
5977
5978 if (NULL == wiphy->bands[i])
5979 {
5980 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[i] is NULL, i = %d",
5981 __func__, i);
5982 continue;
5983 }
5984
5985 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
5986 {
5987 struct ieee80211_supported_band *band = wiphy->bands[i];
5988
5989 if (IEEE80211_BAND_2GHZ == i && eCSR_BAND_5G == pCfg->nBandCapability) // 5G only
5990 {
5991 // Enable social channels for P2P
5992 if (WLAN_HDD_IS_SOCIAL_CHANNEL(band->channels[j].center_freq))
5993 band->channels[j].flags &= ~IEEE80211_CHAN_DISABLED;
5994 else
5995 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
5996 continue;
5997 }
5998 else if (IEEE80211_BAND_5GHZ == i && eCSR_BAND_24 == pCfg->nBandCapability) // 2G only
5999 {
6000 band->channels[j].flags |= IEEE80211_CHAN_DISABLED;
6001 continue;
6002 }
6003 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006004 }
6005 /*Initialise the supported cipher suite details*/
6006 wiphy->cipher_suites = hdd_cipher_suites;
6007 wiphy->n_cipher_suites = ARRAY_SIZE(hdd_cipher_suites);
6008
6009 /*signal strength in mBm (100*dBm) */
6010 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
6011
6012#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Sushant Kaushik4f640e42014-07-08 12:27:09 +05306013 wiphy->max_remain_on_channel_duration = 5000;
Jeff Johnson295189b2012-06-20 16:38:30 -07006014#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006015
Sunil Duttc69bccb2014-05-26 21:30:20 +05306016 wiphy->n_vendor_commands = ARRAY_SIZE(hdd_wiphy_vendor_commands);
6017 wiphy->vendor_commands = hdd_wiphy_vendor_commands;
Rajesh Chauhan98a31f82014-01-06 20:15:25 -08006018 wiphy->vendor_events = wlan_hdd_cfg80211_vendor_events;
6019 wiphy->n_vendor_events = ARRAY_SIZE(wlan_hdd_cfg80211_vendor_events);
6020
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306021 EXIT();
6022 return 0;
6023}
6024
6025/* In this function we are registering wiphy. */
6026int wlan_hdd_cfg80211_register(struct wiphy *wiphy)
6027{
6028 ENTER();
6029 /* Register our wiphy dev with cfg80211 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006030 if (0 > wiphy_register(wiphy))
6031 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306032 /* print error */
Jeff Johnson295189b2012-06-20 16:38:30 -07006033 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy register failed", __func__);
6034 return -EIO;
6035 }
6036
6037 EXIT();
6038 return 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306039}
Jeff Johnson295189b2012-06-20 16:38:30 -07006040
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306041/* In this function we are updating channel list when,
6042 regulatory domain is FCC and country code is US.
6043 Here In FCC standard 5GHz UNII-1 Bands are indoor only.
6044 As per FCC smart phone is not a indoor device.
6045 GO should not opeate on indoor channels */
6046void wlan_hdd_cfg80211_update_reg_info(struct wiphy *wiphy)
6047{
6048 int j;
6049 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
6050 tANI_U8 defaultCountryCode[3] = SME_INVALID_COUNTRY_CODE;
6051 //Default counrtycode from NV at the time of wiphy initialization.
6052 if (eHAL_STATUS_SUCCESS != sme_GetDefaultCountryCodeFrmNv(pHddCtx->hHal,
6053 &defaultCountryCode[0]))
6054 {
Jeff Johnson0299d0a2013-10-30 12:37:43 -07006055 hddLog(LOGE, FL("Failed to get default country code from NV"));
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306056 }
6057 if ((defaultCountryCode[0]== 'U') && (defaultCountryCode[1]=='S'))
6058 {
Madan Mohan Koyyalamudi71278262013-04-12 22:00:48 +05306059 if (NULL == wiphy->bands[IEEE80211_BAND_5GHZ])
6060 {
6061 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: wiphy->bands[IEEE80211_BAND_5GHZ] is NULL",__func__ );
6062 return;
6063 }
6064 for (j = 0; j < wiphy->bands[IEEE80211_BAND_5GHZ]->n_channels; j++)
6065 {
6066 struct ieee80211_supported_band *band = wiphy->bands[IEEE80211_BAND_5GHZ];
6067 // Mark UNII -1 band channel as passive
6068 if (WLAN_HDD_CHANNEL_IN_UNII_1_BAND(band->channels[j].center_freq))
6069 band->channels[j].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
6070 }
6071 }
6072}
6073
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306074/* This function registers for all frame which supplicant is interested in */
6075void wlan_hdd_cfg80211_register_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006076{
Jeff Johnson295189b2012-06-20 16:38:30 -07006077 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6078 /* Register for all P2P action, public action etc frames */
6079 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6080
Jeff Johnsone7245742012-09-05 17:12:55 -07006081 ENTER();
6082
Jeff Johnson295189b2012-06-20 16:38:30 -07006083 /* Right now we are registering these frame when driver is getting
6084 initialized. Once we will move to 2.6.37 kernel, in which we have
6085 frame register ops, we will move this code as a part of that */
6086 /* GAS Initial Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306087 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Jeff Johnson295189b2012-06-20 16:38:30 -07006088 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6089
6090 /* GAS Initial Response */
6091 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6092 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306093
Jeff Johnson295189b2012-06-20 16:38:30 -07006094 /* GAS Comeback Request */
6095 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6096 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6097
6098 /* GAS Comeback Response */
6099 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6100 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6101
6102 /* P2P Public Action */
6103 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306104 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006105 P2P_PUBLIC_ACTION_FRAME_SIZE );
6106
6107 /* P2P Action */
6108 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6109 (v_U8_t*)P2P_ACTION_FRAME,
6110 P2P_ACTION_FRAME_SIZE );
Chet Lanctot186b5732013-03-18 10:26:30 -07006111
Gopichand Nakkalae3d56e72013-04-21 23:33:32 +05306112 /* WNM BSS Transition Request frame */
6113 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6114 (v_U8_t*)WNM_BSS_ACTION_FRAME,
6115 WNM_BSS_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006116
6117 /* WNM-Notification */
6118 sme_RegisterMgmtFrame(hHal, pAdapter->sessionId, type,
6119 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6120 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006121}
6122
Agarwal Ashish8fa0e9a2014-05-23 00:40:12 +05306123void wlan_hdd_cfg80211_deregister_frames(hdd_adapter_t* pAdapter)
Jeff Johnson295189b2012-06-20 16:38:30 -07006124{
Jeff Johnson295189b2012-06-20 16:38:30 -07006125 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
6126 /* Register for all P2P action, public action etc frames */
6127 v_U16_t type = (SIR_MAC_MGMT_FRAME << 2) | ( SIR_MAC_MGMT_ACTION << 4);
6128
Jeff Johnsone7245742012-09-05 17:12:55 -07006129 ENTER();
6130
Jeff Johnson295189b2012-06-20 16:38:30 -07006131 /* Right now we are registering these frame when driver is getting
6132 initialized. Once we will move to 2.6.37 kernel, in which we have
6133 frame register ops, we will move this code as a part of that */
6134 /* GAS Initial Request */
6135
6136 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6137 (v_U8_t*)GAS_INITIAL_REQ, GAS_INITIAL_REQ_SIZE );
6138
6139 /* GAS Initial Response */
6140 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6141 (v_U8_t*)GAS_INITIAL_RSP, GAS_INITIAL_RSP_SIZE );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306142
Jeff Johnson295189b2012-06-20 16:38:30 -07006143 /* GAS Comeback Request */
6144 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6145 (v_U8_t*)GAS_COMEBACK_REQ, GAS_COMEBACK_REQ_SIZE );
6146
6147 /* GAS Comeback Response */
6148 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6149 (v_U8_t*)GAS_COMEBACK_RSP, GAS_COMEBACK_RSP_SIZE );
6150
6151 /* P2P Public Action */
6152 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306153 (v_U8_t*)P2P_PUBLIC_ACTION_FRAME,
Jeff Johnson295189b2012-06-20 16:38:30 -07006154 P2P_PUBLIC_ACTION_FRAME_SIZE );
6155
6156 /* P2P Action */
6157 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6158 (v_U8_t*)P2P_ACTION_FRAME,
6159 P2P_ACTION_FRAME_SIZE );
Leela Venkata Kiran Kumar Reddy Chiralae8e62c82013-10-29 18:23:26 -07006160 /* WNM-Notification */
6161 sme_DeregisterMgmtFrame(hHal, pAdapter->sessionId, type,
6162 (v_U8_t*)WNM_NOTIFICATION_FRAME,
6163 WNM_NOTIFICATION_FRAME_SIZE );
Jeff Johnson295189b2012-06-20 16:38:30 -07006164}
6165
6166#ifdef FEATURE_WLAN_WAPI
6167void wlan_hdd_cfg80211_set_key_wapi(hdd_adapter_t* pAdapter, u8 key_index,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +05306168 const u8 *mac_addr, const u8 *key , int key_Len)
Jeff Johnson295189b2012-06-20 16:38:30 -07006169{
6170 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6171 tCsrRoamSetKey setKey;
6172 v_BOOL_t isConnected = TRUE;
6173 int status = 0;
6174 v_U32_t roamId= 0xFF;
6175 tANI_U8 *pKeyPtr = NULL;
6176 int n = 0;
6177
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306178 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
6179 __func__, hdd_device_modetoString(pAdapter->device_mode),
6180 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07006181
Gopichand Nakkalae7480202013-02-11 15:24:22 +05306182 vos_mem_zero(&setKey, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006183 setKey.keyId = key_index; // Store Key ID
6184 setKey.encType = eCSR_ENCRYPT_TYPE_WPI; // SET WAPI Encryption
6185 setKey.keyDirection = eSIR_TX_RX; // Key Directionn both TX and RX
6186 setKey.paeRole = 0 ; // the PAE role
6187 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
6188 {
6189 vos_set_macaddr_broadcast( (v_MACADDR_t *)setKey.peerMac );
6190 }
6191 else
6192 {
6193 isConnected = hdd_connIsConnected(pHddStaCtx);
6194 vos_mem_copy(setKey.peerMac,&pHddStaCtx->conn_info.bssId,WNI_CFG_BSSID_LEN);
6195 }
6196 setKey.keyLength = key_Len;
6197 pKeyPtr = setKey.Key;
6198 memcpy( pKeyPtr, key, key_Len);
6199
Arif Hussain6d2a3322013-11-17 19:50:10 -08006200 hddLog(VOS_TRACE_LEVEL_INFO,"%s: WAPI KEY LENGTH:0x%04x",
Jeff Johnson295189b2012-06-20 16:38:30 -07006201 __func__, key_Len);
6202 for (n = 0 ; n < key_Len; n++)
6203 hddLog(VOS_TRACE_LEVEL_INFO, "%s WAPI KEY Data[%d]:%02x ",
6204 __func__,n,setKey.Key[n]);
6205
6206 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
6207 if ( isConnected )
6208 {
6209 status= sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
6210 pAdapter->sessionId, &setKey, &roamId );
6211 }
6212 if ( status != 0 )
6213 {
6214 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6215 "[%4d] sme_RoamSetKey returned ERROR status= %d",
6216 __LINE__, status );
6217 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
6218 }
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05306219 /* Need to clear any trace of key value in the memory.
6220 * Thus zero out the memory even though it is local
6221 * variable.
6222 */
6223 vos_mem_zero(&setKey, sizeof(setKey));
Jeff Johnson295189b2012-06-20 16:38:30 -07006224}
6225#endif /* FEATURE_WLAN_WAPI*/
6226
6227#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306228int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -07006229 beacon_data_t **ppBeacon,
6230 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006231#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306232int wlan_hdd_cfg80211_alloc_new_beacon(hdd_adapter_t *pAdapter,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006233 beacon_data_t **ppBeacon,
6234 struct cfg80211_beacon_data *params,
6235 int dtim_period)
6236#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306237{
Jeff Johnson295189b2012-06-20 16:38:30 -07006238 int size;
6239 beacon_data_t *beacon = NULL;
6240 beacon_data_t *old = NULL;
6241 int head_len,tail_len;
6242
Jeff Johnsone7245742012-09-05 17:12:55 -07006243 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -07006244 if (params->head && !params->head_len)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306245 {
6246 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6247 FL("head_len is NULL"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006248 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306249 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006250
6251 old = pAdapter->sessionCtx.ap.beacon;
6252
6253 if (!params->head && !old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306254 {
6255 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6256 FL("session(%d) old and new heads points to NULL"),
6257 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07006258 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306259 }
6260
6261 if (params->tail && !params->tail_len)
6262 {
6263 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6264 FL("tail_len is zero but tail is not NULL"));
6265 return -EINVAL;
6266 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006267
Jeff Johnson295189b2012-06-20 16:38:30 -07006268#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,38))
6269 /* Kernel 3.0 is not updating dtim_period for set beacon */
6270 if (!params->dtim_period)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306271 {
6272 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6273 FL("dtim period is 0"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006274 return -EINVAL;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306275 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006276#endif
6277
6278 if(params->head)
6279 head_len = params->head_len;
6280 else
6281 head_len = old->head_len;
6282
6283 if(params->tail || !old)
6284 tail_len = params->tail_len;
6285 else
6286 tail_len = old->tail_len;
6287
6288 size = sizeof(beacon_data_t) + head_len + tail_len;
6289
6290 beacon = kzalloc(size, GFP_KERNEL);
6291
6292 if( beacon == NULL )
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306293 {
6294 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
6295 FL("Mem allocation for beacon failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -07006296 return -ENOMEM;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306297 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006298
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006299#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006300 if(params->dtim_period || !old )
6301 beacon->dtim_period = params->dtim_period;
6302 else
6303 beacon->dtim_period = old->dtim_period;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006304#else
6305 if(dtim_period || !old )
6306 beacon->dtim_period = dtim_period;
6307 else
6308 beacon->dtim_period = old->dtim_period;
6309#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306310
Jeff Johnson295189b2012-06-20 16:38:30 -07006311 beacon->head = ((u8 *) beacon) + sizeof(beacon_data_t);
6312 beacon->tail = beacon->head + head_len;
6313 beacon->head_len = head_len;
6314 beacon->tail_len = tail_len;
6315
6316 if(params->head) {
6317 memcpy (beacon->head,params->head,beacon->head_len);
6318 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306319 else {
Jeff Johnson295189b2012-06-20 16:38:30 -07006320 if(old)
6321 memcpy (beacon->head,old->head,beacon->head_len);
6322 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306323
Jeff Johnson295189b2012-06-20 16:38:30 -07006324 if(params->tail) {
6325 memcpy (beacon->tail,params->tail,beacon->tail_len);
6326 }
6327 else {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306328 if(old)
Jeff Johnson295189b2012-06-20 16:38:30 -07006329 memcpy (beacon->tail,old->tail,beacon->tail_len);
6330 }
6331
6332 *ppBeacon = beacon;
6333
6334 kfree(old);
6335
6336 return 0;
6337
6338}
Jeff Johnson295189b2012-06-20 16:38:30 -07006339
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05306340v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
6341#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
6342 const v_U8_t *pIes,
6343#else
6344 v_U8_t *pIes,
6345#endif
6346 int length, v_U8_t eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006347{
6348 int left = length;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05306349 v_U8_t *ptr = (v_U8_t *)pIes;
Jeff Johnson295189b2012-06-20 16:38:30 -07006350 v_U8_t elem_id,elem_len;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306351
Jeff Johnson295189b2012-06-20 16:38:30 -07006352 while(left >= 2)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306353 {
Jeff Johnson295189b2012-06-20 16:38:30 -07006354 elem_id = ptr[0];
6355 elem_len = ptr[1];
6356 left -= 2;
6357 if(elem_len > left)
6358 {
6359 hddLog(VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07006360 FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"),
Jeff Johnson295189b2012-06-20 16:38:30 -07006361 eid,elem_len,left);
6362 return NULL;
6363 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306364 if (elem_id == eid)
Jeff Johnson295189b2012-06-20 16:38:30 -07006365 {
6366 return ptr;
6367 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306368
Jeff Johnson295189b2012-06-20 16:38:30 -07006369 left -= elem_len;
6370 ptr += (elem_len + 2);
6371 }
6372 return NULL;
6373}
6374
Jeff Johnson295189b2012-06-20 16:38:30 -07006375/* Check if rate is 11g rate or not */
6376static int wlan_hdd_rate_is_11g(u8 rate)
6377{
Sanjay Devnani28322e22013-06-21 16:13:40 -07006378 static const u8 gRateArray[8] = {12, 18, 24, 36, 48, 72, 96, 108}; /* actual rate * 2 */
Jeff Johnson295189b2012-06-20 16:38:30 -07006379 u8 i;
6380 for (i = 0; i < 8; i++)
6381 {
6382 if(rate == gRateArray[i])
6383 return TRUE;
6384 }
6385 return FALSE;
6386}
6387
6388/* Check for 11g rate and set proper 11g only mode */
6389static void wlan_hdd_check_11gmode(u8 *pIe, u8* require_ht,
6390 u8* pCheckRatesfor11g, eSapPhyMode* pSapHw_mode)
6391{
6392 u8 i, num_rates = pIe[0];
6393
6394 pIe += 1;
6395 for ( i = 0; i < num_rates; i++)
6396 {
6397 if( *pCheckRatesfor11g && (TRUE == wlan_hdd_rate_is_11g(pIe[i] & RATE_MASK)))
6398 {
6399 /* If rate set have 11g rate than change the mode to 11G */
6400 *pSapHw_mode = eSAP_DOT11_MODE_11g;
6401 if (pIe[i] & BASIC_RATE_MASK)
6402 {
6403 /* If we have 11g rate as basic rate, it means mode
6404 is 11g only mode.
6405 */
6406 *pSapHw_mode = eSAP_DOT11_MODE_11g_ONLY;
6407 *pCheckRatesfor11g = FALSE;
6408 }
6409 }
6410 else if((BASIC_RATE_MASK | WLAN_BSS_MEMBERSHIP_SELECTOR_HT_PHY) == pIe[i])
6411 {
6412 *require_ht = TRUE;
6413 }
6414 }
6415 return;
6416}
6417
6418static void wlan_hdd_set_sapHwmode(hdd_adapter_t *pHostapdAdapter)
6419{
6420 tsap_Config_t *pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
6421 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6422 struct ieee80211_mgmt *pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
6423 u8 checkRatesfor11g = TRUE;
6424 u8 require_ht = FALSE;
6425 u8 *pIe=NULL;
6426
6427 pConfig->SapHw_mode= eSAP_DOT11_MODE_11b;
6428
6429 pIe = wlan_hdd_cfg80211_get_ie_ptr(&pMgmt_frame->u.beacon.variable[0],
6430 pBeacon->head_len, WLAN_EID_SUPP_RATES);
6431 if (pIe != NULL)
6432 {
6433 pIe += 1;
6434 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6435 &pConfig->SapHw_mode);
6436 }
6437
6438 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6439 WLAN_EID_EXT_SUPP_RATES);
6440 if (pIe != NULL)
6441 {
6442
6443 pIe += 1;
6444 wlan_hdd_check_11gmode(pIe, &require_ht, &checkRatesfor11g,
6445 &pConfig->SapHw_mode);
6446 }
6447
6448 if( pConfig->channel > 14 )
6449 {
6450 pConfig->SapHw_mode= eSAP_DOT11_MODE_11a;
6451 }
6452
6453 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
6454 WLAN_EID_HT_CAPABILITY);
6455
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306456 if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07006457 {
6458 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n;
6459 if(require_ht)
6460 pConfig->SapHw_mode= eSAP_DOT11_MODE_11n_ONLY;
6461 }
6462}
6463
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306464static int wlan_hdd_add_ie(hdd_adapter_t* pHostapdAdapter, v_U8_t *genie,
6465 v_U8_t *total_ielen, v_U8_t *oui, v_U8_t oui_size)
6466{
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006467 v_U16_t ielen = 0;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306468 v_U8_t *pIe = NULL;
6469 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6470
6471 pIe = wlan_hdd_get_vendor_oui_ie_ptr(oui, oui_size,
6472 pBeacon->tail, pBeacon->tail_len);
6473
6474 if (pIe)
6475 {
6476 ielen = pIe[1] + 2;
6477 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6478 {
6479 vos_mem_copy(&genie[*total_ielen], pIe, ielen);
6480 }
6481 else
6482 {
6483 hddLog( VOS_TRACE_LEVEL_ERROR, "**Ie Length is too big***");
6484 return -EINVAL;
6485 }
6486 *total_ielen += ielen;
6487 }
6488 return 0;
6489}
6490
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006491static void wlan_hdd_add_hostapd_conf_vsie(hdd_adapter_t* pHostapdAdapter,
6492 v_U8_t *genie, v_U8_t *total_ielen)
6493{
6494 beacon_data_t *pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
6495 int left = pBeacon->tail_len;
6496 v_U8_t *ptr = pBeacon->tail;
6497 v_U8_t elem_id, elem_len;
6498 v_U16_t ielen = 0;
6499
6500 if ( NULL == ptr || 0 == left )
6501 return;
6502
6503 while (left >= 2)
6504 {
6505 elem_id = ptr[0];
6506 elem_len = ptr[1];
6507 left -= 2;
6508 if (elem_len > left)
6509 {
6510 hddLog( VOS_TRACE_LEVEL_ERROR,
6511 "****Invalid IEs eid = %d elem_len=%d left=%d*****",
6512 elem_id, elem_len, left);
6513 return;
6514 }
6515 if (IE_EID_VENDOR == elem_id)
6516 {
6517 /* skipping the VSIE's which we don't want to include or
6518 * it will be included by existing code
6519 */
6520 if ((memcmp( &ptr[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) != 0 ) &&
6521#ifdef WLAN_FEATURE_WFD
6522 (memcmp( &ptr[2], WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE) != 0) &&
6523#endif
6524 (memcmp( &ptr[2], WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6525 (memcmp( &ptr[2], BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6526 (memcmp( &ptr[2], "\x00\x50\xf2\x02", WPA_OUI_TYPE_SIZE) != 0) &&
6527 (memcmp( &ptr[2], WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) != 0) &&
6528 (memcmp( &ptr[2], P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE) != 0))
6529 {
6530 ielen = ptr[1] + 2;
6531 if ((*total_ielen + ielen) <= MAX_GENIE_LEN)
6532 {
6533 vos_mem_copy(&genie[*total_ielen], ptr, ielen);
6534 *total_ielen += ielen;
6535 }
6536 else
6537 {
6538 hddLog( VOS_TRACE_LEVEL_ERROR,
6539 "IE Length is too big "
6540 "IEs eid=%d elem_len=%d total_ie_lent=%d",
6541 elem_id, elem_len, *total_ielen);
6542 }
6543 }
6544 }
6545
6546 left -= elem_len;
6547 ptr += (elem_len + 2);
6548 }
6549 return;
6550}
6551
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006552#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07006553static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6554 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07006555#else
6556static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter,
6557 struct cfg80211_beacon_data *params)
6558#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07006559{
6560 v_U8_t *genie;
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306561 v_U8_t total_ielen = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006562 v_U8_t addIE[1] = {0};
Jeff Johnsone7245742012-09-05 17:12:55 -07006563 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07006564
6565 genie = vos_mem_malloc(MAX_GENIE_LEN);
6566
6567 if(genie == NULL) {
6568
6569 return -ENOMEM;
6570 }
6571
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306572 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6573 &total_ielen, WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006574 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306575 hddLog(LOGE,
6576 FL("Adding WPS IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306577 ret = -EINVAL;
6578 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006579 }
6580
6581#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306582 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6583 &total_ielen, WFD_OUI_TYPE, WFD_OUI_TYPE_SIZE))
6584 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306585 hddLog(LOGE,
6586 FL("Adding WFD IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306587 ret = -EINVAL;
6588 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006589 }
6590#endif
6591
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306592 if (0 != wlan_hdd_add_ie(pHostapdAdapter, genie,
6593 &total_ielen, P2P_OUI_TYPE, P2P_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -07006594 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05306595 hddLog(LOGE,
6596 FL("Adding P2P IE failed"));
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306597 ret = -EINVAL;
6598 goto done;
6599 }
6600
6601 if (WLAN_HDD_SOFTAP == pHostapdAdapter->device_mode)
6602 {
Arif Hussaine7f3ea52013-09-12 21:56:36 -07006603 wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen);
Jeff Johnson295189b2012-06-20 16:38:30 -07006604 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006605
6606 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6607 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL,
6608 eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
6609 {
6610 hddLog(LOGE,
6611 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006612 ret = -EINVAL;
6613 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006614 }
6615
6616 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6617 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
6618 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6619 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6620 ==eHAL_STATUS_FAILURE)
6621 {
6622 hddLog(LOGE,
6623 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006624 ret = -EINVAL;
6625 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006626 }
6627
6628 // Added for ProResp IE
6629 if ( (params->proberesp_ies != NULL) && (params->proberesp_ies_len != 0) )
6630 {
6631 u16 rem_probe_resp_ie_len = params->proberesp_ies_len;
6632 u8 probe_rsp_ie_len[3] = {0};
6633 u8 counter = 0;
6634 /* Check Probe Resp Length if it is greater then 255 then Store
6635 Probe Resp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1 &
6636 WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are not able
6637 Store More then 255 bytes into One Variable.
6638 */
6639 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
6640 {
6641 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
6642 {
6643 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
6644 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
6645 }
6646 else
6647 {
6648 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
6649 rem_probe_resp_ie_len = 0;
6650 }
6651 }
6652
6653 rem_probe_resp_ie_len = 0;
6654
6655 if (probe_rsp_ie_len[0] > 0)
6656 {
6657 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6658 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
6659 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6660 probe_rsp_ie_len[0], NULL,
6661 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6662 {
6663 hddLog(LOGE,
6664 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006665 ret = -EINVAL;
6666 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006667 }
6668 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
6669 }
6670
6671 if (probe_rsp_ie_len[1] > 0)
6672 {
6673 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6674 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
6675 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6676 probe_rsp_ie_len[1], NULL,
6677 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6678 {
6679 hddLog(LOGE,
6680 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006681 ret = -EINVAL;
6682 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006683 }
6684 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
6685 }
6686
6687 if (probe_rsp_ie_len[2] > 0)
6688 {
6689 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6690 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
6691 (tANI_U8*)&params->proberesp_ies[rem_probe_resp_ie_len],
6692 probe_rsp_ie_len[2], NULL,
6693 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6694 {
6695 hddLog(LOGE,
6696 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006697 ret = -EINVAL;
6698 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006699 }
6700 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
6701 }
6702
6703 if (probe_rsp_ie_len[1] == 0 )
6704 {
6705 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6706 WNI_CFG_PROBE_RSP_ADDNIE_DATA2, (tANI_U8*)addIE, 0, NULL,
6707 eANI_BOOLEAN_FALSE) )
6708 {
6709 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006710 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006711 }
6712 }
6713
6714 if (probe_rsp_ie_len[2] == 0 )
6715 {
6716 if ( eHAL_STATUS_FAILURE == ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6717 WNI_CFG_PROBE_RSP_ADDNIE_DATA3, (tANI_U8*)addIE, 0, NULL,
6718 eANI_BOOLEAN_FALSE) )
6719 {
6720 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006721 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006722 }
6723 }
6724
6725 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6726 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
6727 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6728 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6729 == eHAL_STATUS_FAILURE)
6730 {
6731 hddLog(LOGE,
6732 "Could not pass on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006733 ret = -EINVAL;
6734 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006735 }
6736 }
6737 else
6738 {
6739 // Reset WNI_CFG_PROBE_RSP Flags
6740 wlan_hdd_reset_prob_rspies(pHostapdAdapter);
6741
6742 hddLog(VOS_TRACE_LEVEL_INFO,
6743 "%s: No Probe Response IE received in set beacon",
6744 __func__);
6745 }
6746
6747 // Added for AssocResp IE
6748 if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) )
6749 {
6750 if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6751 WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies,
6752 params->assocresp_ies_len, NULL,
6753 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
6754 {
6755 hddLog(LOGE,
6756 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006757 ret = -EINVAL;
6758 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006759 }
6760
6761 if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6762 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL,
6763 test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ?
6764 eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE)
6765 == eHAL_STATUS_FAILURE)
6766 {
6767 hddLog(LOGE,
6768 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnsone7245742012-09-05 17:12:55 -07006769 ret = -EINVAL;
6770 goto done;
Jeff Johnson295189b2012-06-20 16:38:30 -07006771 }
6772 }
6773 else
6774 {
6775 hddLog(VOS_TRACE_LEVEL_INFO,
6776 "%s: No Assoc Response IE received in set beacon",
6777 __func__);
6778
6779 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal,
6780 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
6781 eANI_BOOLEAN_FALSE) )
6782 {
6783 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006784 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07006785 }
6786 }
6787
Jeff Johnsone7245742012-09-05 17:12:55 -07006788done:
Jeff Johnson295189b2012-06-20 16:38:30 -07006789 vos_mem_free(genie);
Gopichand Nakkala2b25f4e2013-03-21 19:14:07 +05306790 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07006791}
Jeff Johnson295189b2012-06-20 16:38:30 -07006792
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306793/*
Jeff Johnson295189b2012-06-20 16:38:30 -07006794 * FUNCTION: wlan_hdd_validate_operation_channel
6795 * called by wlan_hdd_cfg80211_start_bss() and
6796 * wlan_hdd_cfg80211_set_channel()
6797 * This function validates whether given channel is part of valid
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306798 * channel list.
6799 */
Varun Reddy Yeturu920df212013-05-22 08:07:23 -07006800VOS_STATUS wlan_hdd_validate_operation_channel(hdd_adapter_t *pAdapter,int channel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006801{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306802
Jeff Johnson295189b2012-06-20 16:38:30 -07006803 v_U32_t num_ch = 0;
6804 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN];
6805 u32 indx = 0;
6806 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306807 v_U8_t fValidChannel = FALSE, count = 0;
6808 hdd_config_t *hdd_pConfig_ini= (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306809
Jeff Johnson295189b2012-06-20 16:38:30 -07006810 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6811
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306812 if ( hdd_pConfig_ini->sapAllowAllChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -07006813 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306814 /* Validate the channel */
6815 for (count = RF_CHAN_1 ; count <= RF_CHAN_165 ; count++)
Jeff Johnson295189b2012-06-20 16:38:30 -07006816 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306817 if ( channel == rfChannels[count].channelNum )
6818 {
6819 fValidChannel = TRUE;
6820 break;
6821 }
6822 }
6823 if (fValidChannel != TRUE)
6824 {
6825 hddLog(VOS_TRACE_LEVEL_ERROR,
6826 "%s: Invalid Channel [%d]", __func__, channel);
6827 return VOS_STATUS_E_FAILURE;
Jeff Johnson295189b2012-06-20 16:38:30 -07006828 }
6829 }
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306830 else
Jeff Johnson295189b2012-06-20 16:38:30 -07006831 {
Madan Mohan Koyylamudi64267f72013-02-05 14:07:08 +05306832 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
6833 valid_ch, &num_ch))
6834 {
6835 hddLog(VOS_TRACE_LEVEL_ERROR,
6836 "%s: failed to get valid channel list", __func__);
6837 return VOS_STATUS_E_FAILURE;
6838 }
6839 for (indx = 0; indx < num_ch; indx++)
6840 {
6841 if (channel == valid_ch[indx])
6842 {
6843 break;
6844 }
6845 }
6846
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306847 if (indx >= num_ch)
6848 {
6849 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6850 {
6851 eCsrBand band;
6852 unsigned int freq;
6853
6854 sme_GetFreqBand(hHal, &band);
6855
6856 if (eCSR_BAND_5G == band)
6857 {
6858#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
6859 if (channel <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
6860 {
6861 freq = ieee80211_channel_to_frequency(channel,
6862 IEEE80211_BAND_2GHZ);
6863 }
6864 else
6865 {
6866 freq = ieee80211_channel_to_frequency(channel,
6867 IEEE80211_BAND_5GHZ);
6868 }
6869#else
6870 freq = ieee80211_channel_to_frequency(channel);
6871#endif
6872 if(WLAN_HDD_IS_SOCIAL_CHANNEL(freq))
6873 return VOS_STATUS_SUCCESS;
6874 }
6875 }
6876
6877 hddLog(VOS_TRACE_LEVEL_ERROR,
6878 "%s: Invalid Channel [%d]", __func__, channel);
6879 return VOS_STATUS_E_FAILURE;
6880 }
Jeff Johnson295189b2012-06-20 16:38:30 -07006881 }
Rashmi Ramanna3b59e122014-04-10 14:45:13 +05306882
Jeff Johnson295189b2012-06-20 16:38:30 -07006883 return VOS_STATUS_SUCCESS;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05306884
Jeff Johnson295189b2012-06-20 16:38:30 -07006885}
6886
Viral Modi3a32cc52013-02-08 11:14:52 -08006887/**
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306888 * FUNCTION: __wlan_hdd_cfg80211_set_channel
Viral Modi3a32cc52013-02-08 11:14:52 -08006889 * This function is used to set the channel number
6890 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05306891static int __wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy, struct net_device *dev,
Viral Modi3a32cc52013-02-08 11:14:52 -08006892 struct ieee80211_channel *chan,
6893 enum nl80211_channel_type channel_type
6894 )
6895{
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306896 hdd_adapter_t *pAdapter = NULL;
Viral Modi3a32cc52013-02-08 11:14:52 -08006897 v_U32_t num_ch = 0;
Jeff Johnson4416a782013-03-25 14:17:50 -07006898 int channel = 0;
Viral Modi3a32cc52013-02-08 11:14:52 -08006899 int freq = chan->center_freq; /* freq is in MHZ */
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306900 hdd_context_t *pHddCtx;
6901 int status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006902
6903 ENTER();
6904
6905 if( NULL == dev )
6906 {
6907 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006908 "%s: Called with dev = NULL.", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006909 return -ENODEV;
6910 }
6911 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05306912
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05306913 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
6914 TRACE_CODE_HDD_CFG80211_SET_CHANNEL, pAdapter->sessionId,
6915 channel_type ));
Viral Modi3a32cc52013-02-08 11:14:52 -08006916 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05306917 "%s: device_mode = %s (%d) freq = %d", __func__,
6918 hdd_device_modetoString(pAdapter->device_mode),
6919 pAdapter->device_mode, chan->center_freq);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306920
6921 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
6922 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306923 if (0 != status)
Viral Modi3a32cc52013-02-08 11:14:52 -08006924 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05306925 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08006926 }
6927
6928 /*
6929 * Do freq to chan conversion
6930 * TODO: for 11a
6931 */
6932
6933 channel = ieee80211_frequency_to_channel(freq);
6934
6935 /* Check freq range */
6936 if ((WNI_CFG_CURRENT_CHANNEL_STAMIN > channel) ||
6937 (WNI_CFG_CURRENT_CHANNEL_STAMAX < channel))
6938 {
6939 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006940 "%s: Channel [%d] is outside valid range from %d to %d",
Viral Modi3a32cc52013-02-08 11:14:52 -08006941 __func__, channel, WNI_CFG_CURRENT_CHANNEL_STAMIN,
6942 WNI_CFG_CURRENT_CHANNEL_STAMAX);
6943 return -EINVAL;
6944 }
6945
6946 num_ch = WNI_CFG_VALID_CHANNEL_LIST_LEN;
6947
Gopichand Nakkala6ab19562013-03-07 13:59:42 +05306948 if ((WLAN_HDD_SOFTAP != pAdapter->device_mode) &&
6949 (WLAN_HDD_P2P_GO != pAdapter->device_mode))
Viral Modi3a32cc52013-02-08 11:14:52 -08006950 {
6951 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pAdapter,channel))
6952 {
6953 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006954 "%s: Invalid Channel [%d]", __func__, channel);
Viral Modi3a32cc52013-02-08 11:14:52 -08006955 return -EINVAL;
6956 }
6957 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
6958 "%s: set channel to [%d] for device mode =%d",
6959 __func__, channel,pAdapter->device_mode);
6960 }
6961 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Viral Modi3a32cc52013-02-08 11:14:52 -08006962 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Viral Modi3a32cc52013-02-08 11:14:52 -08006963 )
6964 {
6965 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
6966 tCsrRoamProfile * pRoamProfile = &pWextState->roamProfile;
6967 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
6968
6969 if (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState)
6970 {
6971 /* Link is up then return cant set channel*/
6972 hddLog( VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006973 "%s: IBSS Associated, can't set the channel", __func__);
Viral Modi3a32cc52013-02-08 11:14:52 -08006974 return -EINVAL;
6975 }
6976
6977 num_ch = pRoamProfile->ChannelInfo.numOfChannels = 1;
6978 pHddStaCtx->conn_info.operationChannel = channel;
6979 pRoamProfile->ChannelInfo.ChannelList =
6980 &pHddStaCtx->conn_info.operationChannel;
6981 }
6982 else if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Viral Modi3a32cc52013-02-08 11:14:52 -08006983 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Viral Modi3a32cc52013-02-08 11:14:52 -08006984 )
6985 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306986 if (WLAN_HDD_P2P_GO == pAdapter->device_mode)
6987 {
6988 if(VOS_STATUS_SUCCESS !=
6989 wlan_hdd_validate_operation_channel(pAdapter,channel))
6990 {
6991 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08006992 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05306993 return -EINVAL;
6994 }
6995 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
6996 }
6997 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
Viral Modi3a32cc52013-02-08 11:14:52 -08006998 {
6999 hdd_config_t *cfg_param = (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini;
7000
7001 /* If auto channel selection is configured as enable/ 1 then ignore
7002 channel set by supplicant
7003 */
7004 if ( cfg_param->apAutoChannelSelection )
7005 {
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307006 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel =
7007 AUTO_CHANNEL_SELECT;
Viral Modi3a32cc52013-02-08 11:14:52 -08007008 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307009 "%s: set channel to auto channel (0) for device mode =%s (%d)",
7010 __func__, hdd_device_modetoString(pAdapter->device_mode),
7011 pAdapter->device_mode);
Viral Modi3a32cc52013-02-08 11:14:52 -08007012 }
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307013 else
7014 {
7015 if(VOS_STATUS_SUCCESS !=
7016 wlan_hdd_validate_operation_channel(pAdapter,channel))
7017 {
7018 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007019 "%s: Invalid Channel [%d]", __func__, channel);
Gopichand Nakkalac8fa7b62013-03-11 13:56:41 +05307020 return -EINVAL;
7021 }
7022 (WLAN_HDD_GET_AP_CTX_PTR(pAdapter))->sapConfig.channel = channel;
7023 }
Viral Modi3a32cc52013-02-08 11:14:52 -08007024 }
7025 }
7026 else
7027 {
7028 hddLog(VOS_TRACE_LEVEL_FATAL,
7029 "%s: Invalid device mode failed to set valid channel", __func__);
7030 return -EINVAL;
7031 }
7032 EXIT();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307033 return status;
Viral Modi3a32cc52013-02-08 11:14:52 -08007034}
7035
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05307036static int wlan_hdd_cfg80211_set_channel( struct wiphy *wiphy,
7037 struct net_device *dev,
7038 struct ieee80211_channel *chan,
7039 enum nl80211_channel_type channel_type
7040 )
7041{
7042 int ret;
7043
7044 vos_ssr_protect(__func__);
7045 ret = __wlan_hdd_cfg80211_set_channel(wiphy, dev, chan, channel_type);
7046 vos_ssr_unprotect(__func__);
7047
7048 return ret;
7049}
7050
Jeff Johnson295189b2012-06-20 16:38:30 -07007051#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7052static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7053 struct beacon_parameters *params)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007054#else
7055static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
7056 struct cfg80211_beacon_data *params,
7057 const u8 *ssid, size_t ssid_len,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307058 enum nl80211_hidden_ssid hidden_ssid,
7059 v_U8_t auth_type)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007060#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007061{
7062 tsap_Config_t *pConfig;
7063 beacon_data_t *pBeacon = NULL;
7064 struct ieee80211_mgmt *pMgmt_frame;
7065 v_U8_t *pIe=NULL;
7066 v_U16_t capab_info;
7067 eCsrAuthType RSNAuthType;
7068 eCsrEncryptionType RSNEncryptType;
7069 eCsrEncryptionType mcRSNEncryptType;
7070 int status = VOS_STATUS_SUCCESS;
7071 tpWLAN_SAPEventCB pSapEventCallback;
7072 hdd_hostapd_state_t *pHostapdState;
7073 v_U8_t wpaRsnIEdata[(SIR_MAC_MAX_IE_LENGTH * 2)+4]; //Max ie length 255 * 2(WPA+RSN) + 2 bytes (vendor specific ID) * 2
7074 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pHostapdAdapter))->pvosContext;
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307075 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pHostapdAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007076 struct qc_mac_acl_entry *acl_entry = NULL;
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307077 hdd_config_t *iniConfig;
Jeff Johnson295189b2012-06-20 16:38:30 -07007078 v_SINT_t i;
Madan Mohan Koyyalamudi543172b2012-12-05 16:40:18 -08007079 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pHostapdAdapter);
Peng Xu2446a892014-09-05 17:21:18 +05307080 tSmeConfigParams *psmeConfig;
Chet Lanctot40142442014-05-20 13:39:25 -07007081 v_BOOL_t MFPCapable = VOS_FALSE;
7082 v_BOOL_t MFPRequired = VOS_FALSE;
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307083 v_BOOL_t sapEnable11AC =
7084 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->sapEnable11AC;
Jeff Johnson295189b2012-06-20 16:38:30 -07007085 ENTER();
7086
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307087 iniConfig = pHddCtx->cfg_ini;
7088
Jeff Johnson295189b2012-06-20 16:38:30 -07007089 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
7090
7091 pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
7092
7093 pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
7094
7095 pMgmt_frame = (struct ieee80211_mgmt*)pBeacon->head;
7096
7097 pConfig->beacon_int = pMgmt_frame->u.beacon.beacon_int;
7098
7099 //channel is already set in the set_channel Call back
7100 //pConfig->channel = pCommitConfig->channel;
7101
7102 /*Protection parameter to enable or disable*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307103 pConfig->protEnabled =
Jeff Johnson295189b2012-06-20 16:38:30 -07007104 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtEnabled;
7105
7106 pConfig->dtim_period = pBeacon->dtim_period;
7107
Arif Hussain6d2a3322013-11-17 19:50:10 -08007108 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
Jeff Johnson295189b2012-06-20 16:38:30 -07007109 pConfig->dtim_period);
7110
Madan Mohan Koyyalamudie0ca11f2012-11-27 15:57:52 -08007111 if (pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson32d95a32012-09-10 13:15:23 -07007112 {
7113 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007114 WLAN_EID_COUNTRY);
Kiet Lam083504c2013-11-25 14:17:45 +05307115 if(memcmp(pHddCtx->cfg_ini->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0)
7116 {
7117 tANI_BOOLEAN restartNeeded;
7118 pConfig->ieee80211d = 1;
7119 vos_mem_copy(pConfig->countryCode, pHddCtx->cfg_ini->apCntryCode, 3);
7120 sme_setRegInfo(hHal, pConfig->countryCode);
7121 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
7122 }
7123 else if(pIe)
Jeff Johnson295189b2012-06-20 16:38:30 -07007124 {
Jeff Johnson32d95a32012-09-10 13:15:23 -07007125 tANI_BOOLEAN restartNeeded;
Jeff Johnson32d95a32012-09-10 13:15:23 -07007126 pConfig->ieee80211d = 1;
7127 vos_mem_copy(pConfig->countryCode, &pIe[2], 3);
7128 sme_setRegInfo(hHal, pConfig->countryCode);
7129 sme_ResetCountryCodeInformation(hHal, &restartNeeded);
Jeff Johnson295189b2012-06-20 16:38:30 -07007130 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007131 else
7132 {
7133 pConfig->ieee80211d = 0;
7134 }
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307135 /*
7136 * If auto channel is configured i.e. channel is 0,
7137 * so skip channel validation.
7138 */
7139 if( AUTO_CHANNEL_SELECT != pConfig->channel )
7140 {
7141 if(VOS_STATUS_SUCCESS != wlan_hdd_validate_operation_channel(pHostapdAdapter,pConfig->channel))
7142 {
7143 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007144 "%s: Invalid Channel [%d]", __func__, pConfig->channel);
Madan Mohan Koyylamudia16d0202013-02-01 11:05:57 +05307145 return -EINVAL;
7146 }
7147 }
7148 else
7149 {
7150 if(1 != pHddCtx->is_dynamic_channel_range_set)
7151 {
7152 hdd_config_t *hdd_pConfig= (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini;
7153 WLANSAP_SetChannelRange(hHal, hdd_pConfig->apStartChannelNum,
7154 hdd_pConfig->apEndChannelNum,hdd_pConfig->apOperatingBand);
7155 }
7156 pHddCtx->is_dynamic_channel_range_set = 0;
7157 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007158 }
Jeff Johnson32d95a32012-09-10 13:15:23 -07007159 else
Jeff Johnson295189b2012-06-20 16:38:30 -07007160 {
7161 pConfig->ieee80211d = 0;
7162 }
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307163
7164#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7165 if (params->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7166 pConfig->authType = eSAP_OPEN_SYSTEM;
7167 else if (params->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7168 pConfig->authType = eSAP_SHARED_KEY;
7169 else
7170 pConfig->authType = eSAP_AUTO_SWITCH;
7171#else
7172 if (auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
7173 pConfig->authType = eSAP_OPEN_SYSTEM;
7174 else if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
7175 pConfig->authType = eSAP_SHARED_KEY;
7176 else
7177 pConfig->authType = eSAP_AUTO_SWITCH;
7178#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007179
7180 capab_info = pMgmt_frame->u.beacon.capab_info;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307181
7182 pConfig->privacy = (pMgmt_frame->u.beacon.capab_info &
Jeff Johnson295189b2012-06-20 16:38:30 -07007183 WLAN_CAPABILITY_PRIVACY) ? VOS_TRUE : VOS_FALSE;
7184
7185 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->uPrivacy = pConfig->privacy;
7186
7187 /*Set wps station to configured*/
7188 pIe = wlan_hdd_get_wps_ie_ptr(pBeacon->tail, pBeacon->tail_len);
7189
7190 if(pIe)
7191 {
7192 if(pIe[1] < (2 + WPS_OUI_TYPE_SIZE))
7193 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007194 hddLog( VOS_TRACE_LEVEL_ERROR, "**Wps Ie Length is too small***");
Jeff Johnson295189b2012-06-20 16:38:30 -07007195 return -EINVAL;
7196 }
7197 else if(memcmp(&pIe[2], WPS_OUI_TYPE, WPS_OUI_TYPE_SIZE) == 0)
7198 {
Madan Mohan Koyyalamudi8bdd3112012-09-24 13:55:14 -07007199 hddLog( VOS_TRACE_LEVEL_INFO, "** WPS IE(len %d) ***", (pIe[1]+2));
Jeff Johnson295189b2012-06-20 16:38:30 -07007200 /* Check 15 bit of WPS IE as it contain information for wps state
7201 * WPS state
7202 */
7203 if(SAP_WPS_ENABLED_UNCONFIGURED == pIe[15])
7204 {
7205 pConfig->wps_state = SAP_WPS_ENABLED_UNCONFIGURED;
7206 } else if(SAP_WPS_ENABLED_CONFIGURED == pIe[15])
7207 {
7208 pConfig->wps_state = SAP_WPS_ENABLED_CONFIGURED;
7209 }
7210 }
7211 }
7212 else
7213 {
7214 pConfig->wps_state = SAP_WPS_DISABLED;
7215 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307216 pConfig->fwdWPSPBCProbeReq = 1; // Forward WPS PBC probe request frame up
Jeff Johnson295189b2012-06-20 16:38:30 -07007217
c_hpothufe599e92014-06-16 11:38:55 +05307218 pConfig->RSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7219 pConfig->mcRSNEncryptType = eCSR_ENCRYPT_TYPE_NONE;
7220 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType =
7221 eCSR_ENCRYPT_TYPE_NONE;
7222
Jeff Johnson295189b2012-06-20 16:38:30 -07007223 pConfig->RSNWPAReqIELength = 0;
7224 pConfig->pRSNWPAReqIE = NULL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307225 pIe = wlan_hdd_cfg80211_get_ie_ptr(pBeacon->tail, pBeacon->tail_len,
Jeff Johnson295189b2012-06-20 16:38:30 -07007226 WLAN_EID_RSN);
7227 if(pIe && pIe[1])
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307228 {
Jeff Johnson295189b2012-06-20 16:38:30 -07007229 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7230 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7231 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307232 /* The actual processing may eventually be more extensive than
7233 * this. Right now, just consume any PMKIDs that are sent in
Jeff Johnson295189b2012-06-20 16:38:30 -07007234 * by the app.
7235 * */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307236 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007237 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7238 &RSNEncryptType,
7239 &mcRSNEncryptType,
7240 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007241 &MFPCapable,
7242 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007243 pConfig->pRSNWPAReqIE[1]+2,
7244 pConfig->pRSNWPAReqIE );
7245
7246 if( VOS_STATUS_SUCCESS == status )
7247 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307248 /* Now copy over all the security attributes you have
7249 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007250 * */
7251 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7252 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7253 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7254 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307255 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007256 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007257 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7258 }
7259 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307260
Jeff Johnson295189b2012-06-20 16:38:30 -07007261 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7262 pBeacon->tail, pBeacon->tail_len);
7263
7264 if(pIe && pIe[1] && (pIe[0] == DOT11F_EID_WPA))
7265 {
7266 if (pConfig->pRSNWPAReqIE)
7267 {
7268 /*Mixed mode WPA/WPA2*/
7269 memcpy((&wpaRsnIEdata[0] + pConfig->RSNWPAReqIELength), pIe, pIe[1] + 2);
7270 pConfig->RSNWPAReqIELength += pIe[1] + 2;
7271 }
7272 else
7273 {
7274 pConfig->RSNWPAReqIELength = pIe[1] + 2;
7275 memcpy(&wpaRsnIEdata[0], pIe, pConfig->RSNWPAReqIELength);
7276 pConfig->pRSNWPAReqIE = &wpaRsnIEdata[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307277 status = hdd_softap_unpackIE(
Jeff Johnson295189b2012-06-20 16:38:30 -07007278 vos_get_context( VOS_MODULE_ID_SME, pVosContext),
7279 &RSNEncryptType,
7280 &mcRSNEncryptType,
7281 &RSNAuthType,
Chet Lanctot8cecea22014-02-11 19:09:36 -08007282 &MFPCapable,
7283 &MFPRequired,
Jeff Johnson295189b2012-06-20 16:38:30 -07007284 pConfig->pRSNWPAReqIE[1]+2,
7285 pConfig->pRSNWPAReqIE );
7286
7287 if( VOS_STATUS_SUCCESS == status )
7288 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307289 /* Now copy over all the security attributes you have
7290 * parsed out
Jeff Johnson295189b2012-06-20 16:38:30 -07007291 * */
7292 pConfig->RSNEncryptType = RSNEncryptType; // Use the cipher type in the RSN IE
7293 pConfig->mcRSNEncryptType = mcRSNEncryptType;
7294 (WLAN_HDD_GET_AP_CTX_PTR(pHostapdAdapter))->ucEncryptType
7295 = RSNEncryptType;
Gopichand Nakkala66c0bd02013-04-10 11:36:29 +05307296 hddLog( LOG1, FL("CSR AuthType = %d, "
Arif Hussain6d2a3322013-11-17 19:50:10 -08007297 "EncryptionType = %d mcEncryptionType = %d"),
Jeff Johnson295189b2012-06-20 16:38:30 -07007298 RSNAuthType, RSNEncryptType, mcRSNEncryptType);
7299 }
7300 }
7301 }
7302
Jeff Johnson4416a782013-03-25 14:17:50 -07007303 if (pConfig->RSNWPAReqIELength > sizeof wpaRsnIEdata) {
7304 hddLog( VOS_TRACE_LEVEL_ERROR, "**RSNWPAReqIELength is too large***");
7305 return -EINVAL;
7306 }
7307
Jeff Johnson295189b2012-06-20 16:38:30 -07007308 pConfig->SSIDinfo.ssidHidden = VOS_FALSE;
7309
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007310#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007311 if (params->ssid != NULL)
7312 {
7313 memcpy(pConfig->SSIDinfo.ssid.ssId, params->ssid, params->ssid_len);
7314 pConfig->SSIDinfo.ssid.length = params->ssid_len;
7315 if (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7316 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7317 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007318#else
7319 if (ssid != NULL)
7320 {
7321 memcpy(pConfig->SSIDinfo.ssid.ssId, ssid, ssid_len);
7322 pConfig->SSIDinfo.ssid.length = ssid_len;
7323 if (hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
7324 pConfig->SSIDinfo.ssidHidden = VOS_TRUE;
7325 }
7326#endif
7327
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307328 vos_mem_copy(pConfig->self_macaddr.bytes,
Jeff Johnson295189b2012-06-20 16:38:30 -07007329 pHostapdAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t));
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307330
Jeff Johnson295189b2012-06-20 16:38:30 -07007331 /* default value */
7332 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
7333 pConfig->num_accept_mac = 0;
7334 pConfig->num_deny_mac = 0;
7335
7336 pIe = wlan_hdd_get_vendor_oui_ie_ptr(BLACKLIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7337 pBeacon->tail, pBeacon->tail_len);
7338
7339 /* pIe for black list is following form:
7340 type : 1 byte
7341 length : 1 byte
7342 OUI : 4 bytes
7343 acl type : 1 byte
7344 no of mac addr in black list: 1 byte
7345 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307346 */
7347 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007348 {
7349 pConfig->SapMacaddr_acl = pIe[6];
7350 pConfig->num_deny_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007351 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no deny mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007352 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307353 if (pConfig->num_deny_mac > MAX_ACL_MAC_ADDRESS)
7354 pConfig->num_deny_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007355 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7356 for (i = 0; i < pConfig->num_deny_mac; i++)
7357 {
7358 vos_mem_copy(&pConfig->deny_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7359 acl_entry++;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307360 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007361 }
7362 pIe = wlan_hdd_get_vendor_oui_ie_ptr(WHITELIST_OUI_TYPE, WPA_OUI_TYPE_SIZE,
7363 pBeacon->tail, pBeacon->tail_len);
7364
7365 /* pIe for white list is following form:
7366 type : 1 byte
7367 length : 1 byte
7368 OUI : 4 bytes
7369 acl type : 1 byte
7370 no of mac addr in white list: 1 byte
7371 list of mac_acl_entries: variable, 6 bytes per mac address + sizeof(int) for vlan id
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307372 */
7373 if ((pIe != NULL) && (pIe[1] != 0))
Jeff Johnson295189b2012-06-20 16:38:30 -07007374 {
7375 pConfig->SapMacaddr_acl = pIe[6];
7376 pConfig->num_accept_mac = pIe[7];
Arif Hussain6d2a3322013-11-17 19:50:10 -08007377 hddLog(VOS_TRACE_LEVEL_INFO,"acl type = %d no accept mac = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07007378 pIe[6], pIe[7]);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307379 if (pConfig->num_accept_mac > MAX_ACL_MAC_ADDRESS)
7380 pConfig->num_accept_mac = MAX_ACL_MAC_ADDRESS;
Jeff Johnson295189b2012-06-20 16:38:30 -07007381 acl_entry = (struct qc_mac_acl_entry *)(pIe + 8);
7382 for (i = 0; i < pConfig->num_accept_mac; i++)
7383 {
7384 vos_mem_copy(&pConfig->accept_mac[i], acl_entry->addr, sizeof(qcmacaddr));
7385 acl_entry++;
7386 }
7387 }
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +05307388
Jeff Johnson295189b2012-06-20 16:38:30 -07007389 wlan_hdd_set_sapHwmode(pHostapdAdapter);
7390
Jeff Johnsone7245742012-09-05 17:12:55 -07007391#ifdef WLAN_FEATURE_11AC
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007392 /* Overwrite the hostapd setting for HW mode only for 11ac.
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307393 * This is valid only if mode is set to 11n in hostapd, sapEnable11AC
7394 * is set in .ini and 11ac is supported by both host and firmware.
Kiet Lam0f320422013-11-21 19:29:17 +05307395 * Otherwise, leave whatever is set in hostapd (a OR b OR g OR n mode)
7396 */
Ravi Kumar Vaishnavbbaebbe2013-01-15 17:09:48 -08007397 if( ((pConfig->SapHw_mode == eSAP_DOT11_MODE_11n) ||
7398 (pConfig->SapHw_mode == eSAP_DOT11_MODE_11n_ONLY)) &&
Sushant Kaushik7dc03272015-02-18 11:25:12 +05307399 (sapEnable11AC) && (sme_IsFeatureSupportedByDriver(DOT11AC)) &&
7400 (sme_IsFeatureSupportedByFW(DOT11AC)) )
Jeff Johnsone7245742012-09-05 17:12:55 -07007401 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307402 v_U32_t operatingBand = 0;
Jeff Johnsone7245742012-09-05 17:12:55 -07007403 pConfig->SapHw_mode = eSAP_DOT11_MODE_11ac;
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307404 ccmCfgGetInt(hHal, WNI_CFG_SAP_CHANNEL_SELECT_OPERATING_BAND, &operatingBand);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007405
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307406 /* If ACS disable and selected channel <= 14
7407 * OR
7408 * ACS enabled and ACS operating band is choosen as 2.4
7409 * AND
7410 * VHT in 2.4G Disabled
7411 * THEN
7412 * Fallback to 11N mode
7413 */
7414 if (((AUTO_CHANNEL_SELECT != pConfig->channel && pConfig->channel <= SIR_11B_CHANNEL_END)
7415 || (AUTO_CHANNEL_SELECT == pConfig->channel &&
Deepthi Gowri7db41f32014-10-13 17:02:29 +05307416 operatingBand == eSAP_RF_SUBBAND_2_4_GHZ)) &&
Siddharth Bhal5cba24e2014-05-08 18:59:39 +05307417 iniConfig->enableVhtFor24GHzBand == FALSE)
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007418 {
Siddharth Bhalf42f8592014-05-15 13:39:07 +05307419 hddLog(LOGW, FL("Setting hwmode to 11n, operatingBand = %d, Channel = %d"),
7420 operatingBand, pConfig->channel);
Ravi Joshi83bfaa12013-05-28 22:12:08 -07007421 pConfig->SapHw_mode = eSAP_DOT11_MODE_11n;
7422 }
Jeff Johnsone7245742012-09-05 17:12:55 -07007423 }
7424#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307425
Jeff Johnson295189b2012-06-20 16:38:30 -07007426 // ht_capab is not what the name conveys,this is used for protection bitmap
7427 pConfig->ht_capab =
7428 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apProtection;
7429
7430 if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) )
7431 {
7432 hddLog(LOGE, FL("SAP Not able to set AP IEs"));
7433 return -EINVAL;
7434 }
7435
7436 //Uapsd Enabled Bit
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307437 pConfig->UapsdEnable =
Jeff Johnson295189b2012-06-20 16:38:30 -07007438 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apUapsdEnabled;
7439 //Enable OBSS protection
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307440 pConfig->obssProtEnabled =
7441 (WLAN_HDD_GET_CTX(pHostapdAdapter))->cfg_ini->apOBSSProtEnabled;
Jeff Johnson295189b2012-06-20 16:38:30 -07007442
Chet Lanctot8cecea22014-02-11 19:09:36 -08007443#ifdef WLAN_FEATURE_11W
7444 pConfig->mfpCapable = MFPCapable;
7445 pConfig->mfpRequired = MFPRequired;
7446 hddLog(LOGW, FL("Soft AP MFP capable %d, MFP required %d\n"),
7447 pConfig->mfpCapable, pConfig->mfpRequired);
7448#endif
7449
Arif Hussain6d2a3322013-11-17 19:50:10 -08007450 hddLog(LOGW, FL("SOftAP macaddress : "MAC_ADDRESS_STR),
Jeff Johnson295189b2012-06-20 16:38:30 -07007451 MAC_ADDR_ARRAY(pHostapdAdapter->macAddressCurrent.bytes));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007452 hddLog(LOGW,FL("ssid =%s, beaconint=%d, channel=%d"),
7453 pConfig->SSIDinfo.ssid.ssId, (int)pConfig->beacon_int,
7454 (int)pConfig->channel);
7455 hddLog(LOGW,FL("hw_mode=%x, privacy=%d, authType=%d"),
7456 pConfig->SapHw_mode, pConfig->privacy,
7457 pConfig->authType);
7458 hddLog(LOGW,FL("RSN/WPALen=%d, Uapsd = %d"),
7459 (int)pConfig->RSNWPAReqIELength, pConfig->UapsdEnable);
7460 hddLog(LOGW,FL("ProtEnabled = %d, OBSSProtEnabled = %d"),
7461 pConfig->protEnabled, pConfig->obssProtEnabled);
Jeff Johnson295189b2012-06-20 16:38:30 -07007462
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307463 if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags))
Jeff Johnson295189b2012-06-20 16:38:30 -07007464 {
7465 //Bss already started. just return.
7466 //TODO Probably it should update some beacon params.
7467 hddLog( LOGE, "Bss Already started...Ignore the request");
7468 EXIT();
7469 return 0;
7470 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307471
Agarwal Ashish51325b52014-06-16 16:50:49 +05307472 if (vos_max_concurrent_connections_reached()) {
7473 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7474 return -EINVAL;
7475 }
7476
Jeff Johnson295189b2012-06-20 16:38:30 -07007477 pConfig->persona = pHostapdAdapter->device_mode;
7478
Peng Xu2446a892014-09-05 17:21:18 +05307479 psmeConfig = (tSmeConfigParams*) vos_mem_malloc(sizeof(tSmeConfigParams));
7480 if ( NULL != psmeConfig)
7481 {
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307482 vos_mem_zero(psmeConfig, sizeof (tSmeConfigParams));
Peng Xu2446a892014-09-05 17:21:18 +05307483 sme_GetConfigParam(hHal, psmeConfig);
7484 pConfig->scanBandPreference = psmeConfig->csrConfig.scanBandPreference;
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +05307485#ifdef WLAN_FEATURE_AP_HT40_24G
7486 if (((pHostapdAdapter->device_mode == WLAN_HDD_SOFTAP)
7487 || (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO))
7488 && pHddCtx->cfg_ini->apHT40_24GEnabled)
7489 {
7490 psmeConfig->csrConfig.apHT40_24GEnabled = 1;
7491 sme_UpdateConfig (hHal, psmeConfig);
7492 }
7493#endif
Peng Xu2446a892014-09-05 17:21:18 +05307494 vos_mem_free(psmeConfig);
7495 }
Peng Xuafc34e32014-09-25 13:23:55 +05307496 pConfig->acsBandSwitchThreshold = iniConfig->acsBandSwitchThreshold;
Peng Xu2446a892014-09-05 17:21:18 +05307497
Jeff Johnson295189b2012-06-20 16:38:30 -07007498 pSapEventCallback = hdd_hostapd_SAPEventCB;
7499 if(WLANSAP_StartBss(pVosContext, pSapEventCallback, pConfig,
7500 (v_PVOID_t)pHostapdAdapter->dev) != VOS_STATUS_SUCCESS)
7501 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08007502 hddLog(LOGE,FL("SAP Start Bss fail"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007503 return -EINVAL;
7504 }
7505
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307506 hddLog(LOG1,
Jeff Johnson295189b2012-06-20 16:38:30 -07007507 FL("Waiting for Scan to complete(auto mode) and BSS to start"));
7508
7509 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307510
Jeff Johnson295189b2012-06-20 16:38:30 -07007511 if (!VOS_IS_STATUS_SUCCESS(status))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307512 {
7513 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007514 ("ERROR: HDD vos wait for single_event failed!!"));
Tushnim Bhattacharyyaad37df12013-10-02 12:01:33 -07007515 smeGetCommandQStatus(hHal);
Jeff Johnson295189b2012-06-20 16:38:30 -07007516 VOS_ASSERT(0);
7517 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307518
Jeff Johnson295189b2012-06-20 16:38:30 -07007519 set_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags);
Kaushik, Sushantf6070802014-10-15 15:09:23 +05307520 /* Initialize WMM configuation */
7521 hdd_wmm_init(pHostapdAdapter);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307522 wlan_hdd_incr_active_session(pHddCtx, pHostapdAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007523
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007524#ifdef WLAN_FEATURE_P2P_DEBUG
7525 if (pHostapdAdapter->device_mode == WLAN_HDD_P2P_GO)
7526 {
7527 if(globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED)
7528 {
7529 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7530 hddLog(LOGE,"[P2P State] From Go nego completed to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007531 "Non-autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007532 }
7533 else if(globalP2PConnectionStatus == P2P_NOT_ACTIVE)
7534 {
7535 globalP2PConnectionStatus = P2P_GO_COMPLETED_STATE;
7536 hddLog(LOGE,"[P2P State] From Inactive to "
Jeff Johnson1250df42012-12-10 14:31:52 -08007537 "Autonomous Group started");
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007538 }
7539 }
7540#endif
7541
Jeff Johnson295189b2012-06-20 16:38:30 -07007542 pHostapdState->bCommit = TRUE;
7543 EXIT();
7544
7545 return 0;
7546}
7547
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007548#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307549static int __wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307550 struct net_device *dev,
Jeff Johnson295189b2012-06-20 16:38:30 -07007551 struct beacon_parameters *params)
7552{
7553 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307554 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307555 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007556
7557 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307558
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307559 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7560 TRACE_CODE_HDD_CFG80211_ADD_BEACON,
7561 pAdapter->sessionId, params->interval));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307562 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "device mode=%s (%d)",
7563 hdd_device_modetoString(pAdapter->device_mode),
7564 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007565
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307566 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7567 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307568 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007569 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307570 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007571 }
7572
Agarwal Ashish51325b52014-06-16 16:50:49 +05307573 if (vos_max_concurrent_connections_reached()) {
7574 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
7575 return -EINVAL;
7576 }
7577
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307578 if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007579 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007580 )
7581 {
7582 beacon_data_t *old,*new;
7583
7584 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307585
Jeff Johnson295189b2012-06-20 16:38:30 -07007586 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307587 {
7588 hddLog(VOS_TRACE_LEVEL_WARN,
7589 FL("already beacon info added to session(%d)"),
7590 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007591 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307592 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007593
7594 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7595
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307596 if(status != VOS_STATUS_SUCCESS)
Jeff Johnson295189b2012-06-20 16:38:30 -07007597 {
7598 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007599 "%s:Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007600 return -EINVAL;
7601 }
7602
7603 pAdapter->sessionCtx.ap.beacon = new;
7604
7605 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7606 }
7607
7608 EXIT();
7609 return status;
7610}
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307611
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307612static int wlan_hdd_cfg80211_add_beacon(struct wiphy *wiphy,
7613 struct net_device *dev,
7614 struct beacon_parameters *params)
7615{
7616 int ret;
7617
7618 vos_ssr_protect(__func__);
7619 ret = __wlan_hdd_cfg80211_add_beacon(wiphy, dev, params);
7620 vos_ssr_unprotect(__func__);
7621
7622 return ret;
7623}
7624
7625static int __wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007626 struct net_device *dev,
7627 struct beacon_parameters *params)
7628{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307629 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307630 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
7631 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307632 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -07007633
7634 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05307635
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307636 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7637 TRACE_CODE_HDD_CFG80211_SET_BEACON,
7638 pAdapter->sessionId, pHddStaCtx->conn_info.authType));
7639 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7640 __func__, hdd_device_modetoString(pAdapter->device_mode),
7641 pAdapter->device_mode);
7642
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307643 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7644 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307645 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007646 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307647 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007648 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307649
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307650 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007651 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307652 )
Jeff Johnson295189b2012-06-20 16:38:30 -07007653 {
7654 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307655
Jeff Johnson295189b2012-06-20 16:38:30 -07007656 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307657
Jeff Johnson295189b2012-06-20 16:38:30 -07007658 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307659 {
7660 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7661 FL("session(%d) old and new heads points to NULL"),
7662 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007663 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307664 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007665
7666 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,&new,params);
7667
7668 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307669 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007670 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007671 return -EINVAL;
7672 }
7673
7674 pAdapter->sessionCtx.ap.beacon = new;
7675
7676 status = wlan_hdd_cfg80211_start_bss(pAdapter, params);
7677 }
7678
7679 EXIT();
7680 return status;
7681}
7682
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307683static int wlan_hdd_cfg80211_set_beacon(struct wiphy *wiphy,
7684 struct net_device *dev,
7685 struct beacon_parameters *params)
7686{
7687 int ret;
7688
7689 vos_ssr_protect(__func__);
7690 ret = __wlan_hdd_cfg80211_set_beacon(wiphy, dev, params);
7691 vos_ssr_unprotect(__func__);
7692
7693 return ret;
7694}
7695
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007696#endif //(LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7697
7698#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307699static int __wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07007700 struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007701#else
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307702static int __wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007703 struct net_device *dev)
7704#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007705{
7706 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Jeff Johnsone7245742012-09-05 17:12:55 -07007707 hdd_context_t *pHddCtx = NULL;
7708 hdd_scaninfo_t *pScanInfo = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307709 VOS_STATUS status;
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307710 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07007711
7712 ENTER();
7713
7714 if (NULL == pAdapter)
7715 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307716 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07007717 "%s: HDD adapter context is Null", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007718 return -ENODEV;
7719 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007720
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307721 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7722 TRACE_CODE_HDD_CFG80211_STOP_AP,
7723 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307724 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7725 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307726 if (0 != status)
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007727 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307728 return status;
Jeff Johnson4416a782013-03-25 14:17:50 -07007729 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007730
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -07007731 pScanInfo = &pHddCtx->scan_info;
7732
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307733 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
7734 __func__, hdd_device_modetoString(pAdapter->device_mode),
7735 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007736
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307737 ret = wlan_hdd_scan_abort(pAdapter);
7738
Girish Gowli4bf7a632014-06-12 13:42:11 +05307739 if (ret < 0)
Jeff Johnsone7245742012-09-05 17:12:55 -07007740 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307741 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7742 FL("Timeout occurred while waiting for abortscan %ld"), ret);
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307743
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307744 if (pHddCtx->isLogpInProgress)
Jeff Johnsone7245742012-09-05 17:12:55 -07007745 {
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307746 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7747 "%s: LOGP in Progress. Ignore!!!", __func__);
Yue Ma4f55ef32014-01-23 16:45:33 -08007748
Jeff Johnsone7245742012-09-05 17:12:55 -07007749 VOS_ASSERT(pScanInfo->mScanPending);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307750 return -EAGAIN;
Jeff Johnsone7245742012-09-05 17:12:55 -07007751 }
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +05307752 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -07007753 }
7754
Rashmi Ramanna1f0948d2014-08-28 15:33:48 +05307755 /* Delete all associated STAs before stopping AP/P2P GO */
7756 hdd_del_all_sta(pAdapter);
Arun Kumar Khandavallia3bd8002014-01-17 16:21:19 +05307757 hdd_hostapd_stop(dev);
7758
Jeff Johnson295189b2012-06-20 16:38:30 -07007759 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07007760 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07007761 )
7762 {
7763 beacon_data_t *old;
7764
7765 old = pAdapter->sessionCtx.ap.beacon;
7766
7767 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307768 {
7769 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
7770 FL("session(%d) beacon data points to NULL"),
7771 pAdapter->sessionId);
Jeff Johnson295189b2012-06-20 16:38:30 -07007772 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307773 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007774
Jeff Johnson295189b2012-06-20 16:38:30 -07007775 hdd_cleanup_actionframe(pHddCtx, pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07007776
7777 mutex_lock(&pHddCtx->sap_lock);
7778 if(test_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags))
7779 {
Jeff Johnson4416a782013-03-25 14:17:50 -07007780 if ( VOS_STATUS_SUCCESS == (status = WLANSAP_StopBss(pHddCtx->pvosContext) ) )
Jeff Johnson295189b2012-06-20 16:38:30 -07007781 {
7782 hdd_hostapd_state_t *pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
7783
7784 status = vos_wait_single_event(&pHostapdState->vosEvent, 10000);
7785
7786 if (!VOS_IS_STATUS_SUCCESS(status))
7787 {
7788 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007789 ("ERROR: HDD vos wait for single_event failed!!"));
Jeff Johnson295189b2012-06-20 16:38:30 -07007790 VOS_ASSERT(0);
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307791 }
7792 }
Jeff Johnson295189b2012-06-20 16:38:30 -07007793 clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags);
Agarwal Ashish51325b52014-06-16 16:50:49 +05307794 /* BSS stopped, clear the active sessions for this device mode */
7795 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07007796 }
7797 mutex_unlock(&pHddCtx->sap_lock);
7798
7799 if(status != VOS_STATUS_SUCCESS)
7800 {
7801 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007802 "%s:Error!!! Stopping the BSS",__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07007803 return -EINVAL;
7804 }
7805
Jeff Johnson4416a782013-03-25 14:17:50 -07007806 if (ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007807 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE)
7808 ==eHAL_STATUS_FAILURE)
7809 {
7810 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007811 "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007812 }
7813
Jeff Johnson4416a782013-03-25 14:17:50 -07007814 if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal,
Jeff Johnson295189b2012-06-20 16:38:30 -07007815 WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL,
7816 eANI_BOOLEAN_FALSE) )
7817 {
7818 hddLog(LOGE,
Arif Hussain6d2a3322013-11-17 19:50:10 -08007819 "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM");
Jeff Johnson295189b2012-06-20 16:38:30 -07007820 }
7821
7822 // Reset WNI_CFG_PROBE_RSP Flags
7823 wlan_hdd_reset_prob_rspies(pAdapter);
7824
7825 pAdapter->sessionCtx.ap.beacon = NULL;
7826 kfree(old);
Madan Mohan Koyyalamudi26bd7142012-10-30 18:14:19 -07007827#ifdef WLAN_FEATURE_P2P_DEBUG
7828 if((pAdapter->device_mode == WLAN_HDD_P2P_GO) &&
7829 (globalP2PConnectionStatus == P2P_GO_COMPLETED_STATE))
7830 {
7831 hddLog(LOGE,"[P2P State] From GO completed to Inactive state "
7832 "GO got removed");
7833 globalP2PConnectionStatus = P2P_NOT_ACTIVE;
7834 }
7835#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07007836 }
7837 EXIT();
7838 return status;
7839}
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007840
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307841#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7842static int wlan_hdd_cfg80211_del_beacon(struct wiphy *wiphy,
7843 struct net_device *dev)
7844{
7845 int ret;
7846
7847 vos_ssr_protect(__func__);
7848 ret = __wlan_hdd_cfg80211_del_beacon(wiphy, dev);
7849 vos_ssr_unprotect(__func__);
7850
7851 return ret;
7852}
7853#else
7854static int wlan_hdd_cfg80211_stop_ap(struct wiphy *wiphy,
7855 struct net_device *dev)
7856{
7857 int ret;
7858
7859 vos_ssr_protect(__func__);
7860 ret = __wlan_hdd_cfg80211_stop_ap(wiphy, dev);
7861 vos_ssr_unprotect(__func__);
7862
7863 return ret;
7864}
7865#endif
7866
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007867#if (LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
7868
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307869static int __wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307870 struct net_device *dev,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007871 struct cfg80211_ap_settings *params)
7872{
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307873 hdd_adapter_t *pAdapter;
7874 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307875 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007876
7877 ENTER();
7878
Girish Gowlib143d7a2015-02-18 19:39:55 +05307879 if (NULL == dev || NULL == params)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007880 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307881 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Girish Gowlib143d7a2015-02-18 19:39:55 +05307882 "%s: Device or params is Null", __func__);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307883 return -ENODEV;
7884 }
7885
7886 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
7887 if (NULL == pAdapter)
7888 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307889 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307890 "%s: HDD adapter is Null", __func__);
7891 return -ENODEV;
7892 }
7893
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307894 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7895 TRACE_CODE_HDD_CFG80211_START_AP, pAdapter->sessionId,
7896 params-> beacon_interval));
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307897 if (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic)
7898 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307899 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307900 "%s: HDD adapter magic is invalid", __func__);
7901 return -ENODEV;
7902 }
7903
7904 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307905 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307906 if (0 != status)
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307907 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307908 return status;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307909 }
7910
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05307911 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device mode = %s (%d)",
7912 __func__, hdd_device_modetoString(pAdapter->device_mode),
7913 pAdapter->device_mode);
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307914
7915 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007916 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007917 )
7918 {
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307919 beacon_data_t *old, *new;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007920
7921 old = pAdapter->sessionCtx.ap.beacon;
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307922
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007923 if (old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307924 {
7925 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
7926 FL("already beacon info added to session(%d)"),
7927 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007928 return -EALREADY;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05307929 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007930
Girish Gowlib143d7a2015-02-18 19:39:55 +05307931#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
7932 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7933 &new,
7934 &params->beacon);
7935#else
7936 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter,
7937 &new,
7938 &params->beacon,
7939 params->dtim_period);
7940#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007941
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307942 if (status != 0)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007943 {
7944 hddLog(VOS_TRACE_LEVEL_FATAL,
Pratik Bhalgata0c7f262012-11-22 17:40:24 +05307945 "%s:Error!!! Allocating the new beacon", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007946 return -EINVAL;
7947 }
7948 pAdapter->sessionCtx.ap.beacon = new;
Viral Modi3a32cc52013-02-08 11:14:52 -08007949#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
Yue Maf49ba872013-08-19 12:04:25 -07007950 wlan_hdd_cfg80211_set_channel(wiphy, dev,
7951#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,8,0))
7952 params->channel, params->channel_type);
7953#else
7954 params->chandef.chan, cfg80211_get_chandef_type(&(params->chandef)));
7955#endif
Viral Modi3a32cc52013-02-08 11:14:52 -08007956#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007957 status = wlan_hdd_cfg80211_start_bss(pAdapter, &params->beacon, params->ssid,
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05307958 params->ssid_len, params->hidden_ssid,
7959 params->auth_type);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007960 }
7961
7962 EXIT();
7963 return status;
7964}
7965
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307966static int wlan_hdd_cfg80211_start_ap(struct wiphy *wiphy,
7967 struct net_device *dev,
7968 struct cfg80211_ap_settings *params)
7969{
7970 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007971
Mukul Sharmab0e0a982014-12-15 18:58:53 +05307972 vos_ssr_protect(__func__);
7973 ret = __wlan_hdd_cfg80211_start_ap(wiphy, dev, params);
7974 vos_ssr_unprotect(__func__);
7975
7976 return ret;
7977}
7978
7979static int __wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007980 struct net_device *dev,
7981 struct cfg80211_beacon_data *params)
7982{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05307983 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307984 hdd_context_t *pHddCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307985 int status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007986
7987 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05307988
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05307989 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
7990 TRACE_CODE_HDD_CFG80211_CHANGE_BEACON,
7991 pAdapter->sessionId, pAdapter->device_mode));
Arif Hussain6d2a3322013-11-17 19:50:10 -08007992 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d",
Jeff Johnson04dd8a82012-06-29 20:41:40 -07007993 __func__, pAdapter->device_mode);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307994
7995 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
7996 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307997 if (0 != status)
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07007998 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05307999 return status;
Madan Mohan Koyyalamudib2c36892012-10-18 20:52:38 -07008000 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008001
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308002 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008003 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308004 )
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008005 {
8006 beacon_data_t *old,*new;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308007
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008008 old = pAdapter->sessionCtx.ap.beacon;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308009
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008010 if (!old)
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308011 {
8012 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8013 FL("session(%d) beacon data points to NULL"),
8014 pAdapter->sessionId);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008015 return -ENOENT;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308016 }
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008017
8018 status = wlan_hdd_cfg80211_alloc_new_beacon(pAdapter, &new, params, 0);
8019
8020 if(status != VOS_STATUS_SUCCESS) {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308021 hddLog(VOS_TRACE_LEVEL_FATAL,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008022 "%s: Error!!! Allocating the new beacon",__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008023 return -EINVAL;
8024 }
8025
8026 pAdapter->sessionCtx.ap.beacon = new;
8027
Kanchanapally, Vidyullathaacc59252015-05-20 16:49:07 +05308028 status = wlan_hdd_cfg80211_start_bss(pAdapter, params, NULL, 0, 0,
8029 pAdapter->sessionCtx.ap.sapConfig.authType);
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008030 }
8031
8032 EXIT();
8033 return status;
8034}
8035
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308036static int wlan_hdd_cfg80211_change_beacon(struct wiphy *wiphy,
8037 struct net_device *dev,
8038 struct cfg80211_beacon_data *params)
8039{
8040 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008041
Mukul Sharmab0e0a982014-12-15 18:58:53 +05308042 vos_ssr_protect(__func__);
8043 ret = __wlan_hdd_cfg80211_change_beacon(wiphy, dev, params);
8044 vos_ssr_unprotect(__func__);
8045
8046 return ret;
8047}
8048
8049#endif //(LINUX_VERSION_CODE > KERNEL_VERSION(3,3,0))
Jeff Johnson295189b2012-06-20 16:38:30 -07008050
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308051static int __wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008052 struct net_device *dev,
8053 struct bss_parameters *params)
8054{
8055 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308056 hdd_context_t *pHddCtx;
8057 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07008058
8059 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308060
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308061 if (NULL == pAdapter)
8062 {
8063 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8064 "%s: HDD adapter is Null", __func__);
8065 return -ENODEV;
8066 }
8067 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308068 ret = wlan_hdd_validate_context(pHddCtx);
8069 if (0 != ret)
8070 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308071 return ret;
8072 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308073 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8074 TRACE_CODE_HDD_CFG80211_CHANGE_BSS,
8075 pAdapter->sessionId, params->ap_isolate));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308076 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8077 __func__, hdd_device_modetoString(pAdapter->device_mode),
8078 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008079
8080 if((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008081 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308082 )
Jeff Johnson295189b2012-06-20 16:38:30 -07008083 {
8084 /* ap_isolate == -1 means that in change bss, upper layer doesn't
8085 * want to update this parameter */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308086 if (-1 != params->ap_isolate)
Jeff Johnson295189b2012-06-20 16:38:30 -07008087 {
8088 pAdapter->sessionCtx.ap.apDisableIntraBssFwd = !!params->ap_isolate;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308089 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008090 }
8091
8092 EXIT();
8093 return 0;
8094}
8095
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +05308096static int wlan_hdd_cfg80211_change_bss (struct wiphy *wiphy,
8097 struct net_device *dev,
8098 struct bss_parameters *params)
8099{
8100 int ret;
8101
8102 vos_ssr_protect(__func__);
8103 ret = __wlan_hdd_cfg80211_change_bss(wiphy, dev, params);
8104 vos_ssr_unprotect(__func__);
8105
8106 return ret;
8107}
Kiet Lam10841362013-11-01 11:36:50 +05308108/* FUNCTION: wlan_hdd_change_country_code_cd
8109* to wait for contry code completion
8110*/
8111void* wlan_hdd_change_country_code_cb(void *pAdapter)
8112{
8113 hdd_adapter_t *call_back_pAdapter = pAdapter;
8114 complete(&call_back_pAdapter->change_country_code);
8115 return NULL;
8116}
8117
Jeff Johnson295189b2012-06-20 16:38:30 -07008118/*
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308119 * FUNCTION: __wlan_hdd_cfg80211_change_iface
Jeff Johnson295189b2012-06-20 16:38:30 -07008120 * This function is used to set the interface type (INFRASTRUCTURE/ADHOC)
8121 */
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308122int __wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008123 struct net_device *ndev,
8124 enum nl80211_iftype type,
8125 u32 *flags,
8126 struct vif_params *params
8127 )
8128{
8129 struct wireless_dev *wdev;
8130 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008131 hdd_context_t *pHddCtx;
Mohit Khanna0f232092012-09-11 14:46:08 -07008132 hdd_adapter_t *pP2pAdapter = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008133 tCsrRoamProfile *pRoamProfile = NULL;
8134 eCsrRoamBssType LastBSSType;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308135 hdd_config_t *pConfig = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07008136 eMib_dot11DesiredBssType connectedBssType;
8137 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308138 long ret;
Jeff Johnson295189b2012-06-20 16:38:30 -07008139
8140 ENTER();
8141
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308142 if (!pAdapter)
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008143 {
8144 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8145 "%s: Adapter context is null", __func__);
8146 return VOS_STATUS_E_FAILURE;
8147 }
8148
8149 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
8150 if (!pHddCtx)
8151 {
8152 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8153 "%s: HDD context is null", __func__);
8154 return VOS_STATUS_E_FAILURE;
8155 }
8156
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308157 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8158 TRACE_CODE_HDD_CFG80211_CHANGE_IFACE,
8159 pAdapter->sessionId, type));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308160 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308161 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -07008162 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308163 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07008164 }
8165
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308166 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
8167 __func__, hdd_device_modetoString(pAdapter->device_mode),
8168 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008169
Agarwal Ashish51325b52014-06-16 16:50:49 +05308170 if (vos_max_concurrent_connections_reached()) {
8171 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
8172 return -EINVAL;
8173 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05308174 pConfig = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -07008175 wdev = ndev->ieee80211_ptr;
8176
8177#ifdef WLAN_BTAMP_FEATURE
8178 if((NL80211_IFTYPE_P2P_CLIENT == type)||
8179 (NL80211_IFTYPE_ADHOC == type)||
8180 (NL80211_IFTYPE_AP == type)||
8181 (NL80211_IFTYPE_P2P_GO == type))
8182 {
8183 pHddCtx->isAmpAllowed = VOS_FALSE;
8184 // stop AMP traffic
8185 status = WLANBAP_StopAmp();
8186 if(VOS_STATUS_SUCCESS != status )
8187 {
8188 pHddCtx->isAmpAllowed = VOS_TRUE;
8189 hddLog(VOS_TRACE_LEVEL_FATAL,
8190 "%s: Failed to stop AMP", __func__);
8191 return -EINVAL;
8192 }
8193 }
8194#endif //WLAN_BTAMP_FEATURE
8195 /* Reset the current device mode bit mask*/
8196 wlan_hdd_clear_concurrency_mode(pHddCtx, pAdapter->device_mode);
8197
Masti, Narayanraddifdde4d02015-04-16 14:41:51 +05308198 /* Notify Mode change in case of concurrency.
8199 * Below function invokes TDLS teardown Functionality Since TDLS is
8200 * not Supported in case of concurrency i.e Once P2P session
8201 * is detected disable offchannel and teardown TDLS links
8202 */
8203 hdd_tdls_notify_mode_change(pAdapter, pHddCtx);
8204
Jeff Johnson295189b2012-06-20 16:38:30 -07008205 if( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07008206 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnsone7245742012-09-05 17:12:55 -07008207 || (pAdapter->device_mode == WLAN_HDD_P2P_DEVICE)
Jeff Johnson295189b2012-06-20 16:38:30 -07008208 )
8209 {
8210 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -08008211 if (!pWextState)
8212 {
8213 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8214 "%s: pWextState is null", __func__);
8215 return VOS_STATUS_E_FAILURE;
8216 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008217 pRoamProfile = &pWextState->roamProfile;
8218 LastBSSType = pRoamProfile->BSSType;
8219
8220 switch (type)
8221 {
8222 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008223 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008224 hddLog(VOS_TRACE_LEVEL_INFO,
8225 "%s: setting interface Type to INFRASTRUCTURE", __func__);
8226 pRoamProfile->BSSType = eCSR_BSS_TYPE_INFRASTRUCTURE;
Jeff Johnsone7245742012-09-05 17:12:55 -07008227#ifdef WLAN_FEATURE_11AC
8228 if(pConfig->dot11Mode == eHDD_DOT11_MODE_AUTO)
8229 {
8230 pConfig->dot11Mode = eHDD_DOT11_MODE_11ac;
8231 }
8232#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308233 pRoamProfile->phyMode =
Jeff Johnsone7245742012-09-05 17:12:55 -07008234 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008235 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008236 //Check for sub-string p2p to confirm its a p2p interface
8237 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308238 {
Mahesh A Saptasagarc48ae8a2015-08-09 00:04:35 +05308239#ifdef FEATURE_WLAN_TDLS
8240 mutex_lock(&pHddCtx->tdls_lock);
8241 wlan_hdd_tdls_exit(pAdapter, TRUE);
8242 mutex_unlock(&pHddCtx->tdls_lock);
8243#endif
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008244 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8245 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8246 }
8247 else
8248 {
8249 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008250 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008251 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008252 break;
Mahesh A Saptasagar36cdc802015-01-07 18:41:17 +05308253
Jeff Johnson295189b2012-06-20 16:38:30 -07008254 case NL80211_IFTYPE_ADHOC:
8255 hddLog(VOS_TRACE_LEVEL_INFO,
8256 "%s: setting interface Type to ADHOC", __func__);
8257 pRoamProfile->BSSType = eCSR_BSS_TYPE_START_IBSS;
8258 pRoamProfile->phyMode =
8259 hdd_cfg_xlate_to_csr_phy_mode(pConfig->dot11Mode);
Shailender Karmuchia734f332013-04-19 14:02:48 -07008260 pAdapter->device_mode = WLAN_HDD_IBSS;
Jeff Johnson295189b2012-06-20 16:38:30 -07008261 wdev->iftype = type;
Katya Nigam1fd24402015-02-16 14:52:19 +05308262 hdd_set_ibss_ops( pAdapter );
8263 hdd_ibss_init_tx_rx( pAdapter );
Nirav Shah7e3c8132015-06-22 23:51:42 +05308264
8265 status = hdd_sta_id_hash_attach(pAdapter);
8266 if (VOS_STATUS_SUCCESS != status) {
8267 hddLog(VOS_TRACE_LEVEL_ERROR,
8268 FL("Failed to initialize hash for IBSS"));
8269 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008270 break;
8271
8272 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008273 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008274 {
8275 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
8276 "%s: setting interface Type to %s", __func__,
8277 (type == NL80211_IFTYPE_AP) ? "SoftAP" : "P2pGo");
8278
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008279 //Cancel any remain on channel for GO mode
8280 if (NL80211_IFTYPE_P2P_GO == type)
8281 {
8282 wlan_hdd_cancel_existing_remain_on_channel(pAdapter);
8283 }
Mohit Khanna0f232092012-09-11 14:46:08 -07008284 if (NL80211_IFTYPE_AP == type)
8285 {
8286 /* As Loading WLAN Driver one interface being created for p2p device
8287 * address. This will take one HW STA and the max number of clients
8288 * that can connect to softAP will be reduced by one. so while changing
8289 * the interface type to NL80211_IFTYPE_AP (SoftAP) remove p2p0
8290 * interface as it is not required in SoftAP mode.
8291 */
8292
8293 // Get P2P Adapter
8294 pP2pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_P2P_DEVICE);
8295
8296 if (pP2pAdapter)
8297 {
Agarwal Ashish3a38bd12014-06-12 15:16:52 +05308298 hdd_stop_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
c_hpothu002231a2015-02-05 14:58:51 +05308299 hdd_deinit_adapter(pHddCtx, pP2pAdapter, TRUE);
Mohit Khanna0f232092012-09-11 14:46:08 -07008300 hdd_close_adapter(pHddCtx, pP2pAdapter, VOS_TRUE);
8301 }
8302 }
Swaroop Goltia2e32212014-04-09 23:37:33 +05308303 //Disable IMPS & BMPS for SAP/GO
8304 if(VOS_STATUS_E_FAILURE ==
8305 hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_P2P_GO))
8306 {
8307 //Fail to Exit BMPS
8308 VOS_ASSERT(0);
8309 }
Deepthi Gowri500fc472014-08-11 19:53:10 +05308310
8311 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
8312
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308313#ifdef FEATURE_WLAN_TDLS
Mohit Khanna0f232092012-09-11 14:46:08 -07008314
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308315 /* A Mutex Lock is introduced while changing the mode to
8316 * protect the concurrent access for the Adapters by TDLS
8317 * module.
8318 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308319 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308320#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008321 //De-init the adapter.
c_hpothu002231a2015-02-05 14:58:51 +05308322 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008323 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
Jeff Johnson295189b2012-06-20 16:38:30 -07008324 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8325 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308326#ifdef FEATURE_WLAN_TDLS
8327 mutex_unlock(&pHddCtx->tdls_lock);
8328#endif
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008329 if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) &&
8330 (pConfig->apRandomBssidEnabled))
8331 {
8332 /* To meet Android requirements create a randomized
8333 MAC address of the form 02:1A:11:Fx:xx:xx */
8334 get_random_bytes(&ndev->dev_addr[3], 3);
8335 ndev->dev_addr[0] = 0x02;
8336 ndev->dev_addr[1] = 0x1A;
8337 ndev->dev_addr[2] = 0x11;
8338 ndev->dev_addr[3] |= 0xF0;
8339 memcpy(pAdapter->macAddressCurrent.bytes, ndev->dev_addr,
8340 VOS_MAC_ADDR_SIZE);
Arif Hussain24bafea2013-11-15 15:10:03 -08008341 pr_info("wlan: Generated HotSpot BSSID " MAC_ADDRESS_STR"\n",
8342 MAC_ADDR_ARRAY(ndev->dev_addr));
Madan Mohan Koyyalamudi3ff2a0b2012-10-15 14:33:46 -07008343 }
8344
Jeff Johnson295189b2012-06-20 16:38:30 -07008345 hdd_set_ap_ops( pAdapter->dev );
8346
Kiet Lam10841362013-11-01 11:36:50 +05308347 /* This is for only SAP mode where users can
8348 * control country through ini.
8349 * P2P GO follows station country code
8350 * acquired during the STA scanning. */
8351 if((NL80211_IFTYPE_AP == type) &&
8352 (memcmp(pConfig->apCntryCode, CFG_AP_COUNTRY_CODE_DEFAULT, 3) != 0))
8353 {
8354 int status = 0;
8355 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_INFO,
8356 "%s: setting country code from INI ", __func__);
8357 init_completion(&pAdapter->change_country_code);
8358 status = (int)sme_ChangeCountryCode(pHddCtx->hHal,
8359 (void *)(tSmeChangeCountryCallback)
8360 wlan_hdd_change_country_code_cb,
8361 pConfig->apCntryCode, pAdapter,
8362 pHddCtx->pvosContext,
Abhishek Singha306a442013-11-07 18:39:01 +05308363 eSIR_FALSE,
8364 eSIR_TRUE);
Kiet Lam10841362013-11-01 11:36:50 +05308365 if (eHAL_STATUS_SUCCESS == status)
8366 {
8367 /* Wait for completion */
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308368 ret = wait_for_completion_interruptible_timeout(
Kiet Lam10841362013-11-01 11:36:50 +05308369 &pAdapter->change_country_code,
8370 msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308371 if (ret <= 0)
Kiet Lam10841362013-11-01 11:36:50 +05308372 {
8373 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308374 FL("SME Timed out while setting country code %ld"),
8375 ret);
Yue Ma4f55ef32014-01-23 16:45:33 -08008376
8377 if (pHddCtx->isLogpInProgress)
8378 {
8379 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8380 "%s: LOGP in Progress. Ignore!!!", __func__);
8381 return -EAGAIN;
8382 }
Kiet Lam10841362013-11-01 11:36:50 +05308383 }
8384 }
8385 else
8386 {
8387 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -08008388 "%s: SME Change Country code failed",__func__);
Kiet Lam10841362013-11-01 11:36:50 +05308389 return -EINVAL;
8390 }
8391 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008392 status = hdd_init_ap_mode(pAdapter);
8393 if(status != VOS_STATUS_SUCCESS)
8394 {
8395 hddLog(VOS_TRACE_LEVEL_FATAL,
8396 "%s: Error initializing the ap mode", __func__);
8397 return -EINVAL;
8398 }
8399 hdd_set_conparam(1);
8400
Nirav Shah7e3c8132015-06-22 23:51:42 +05308401 status = hdd_sta_id_hash_attach(pAdapter);
8402 if (VOS_STATUS_SUCCESS != status)
8403 {
8404 hddLog(VOS_TRACE_LEVEL_ERROR,
8405 FL("Failed to initialize hash for AP"));
8406 return -EINVAL;
8407 }
8408
Jeff Johnson295189b2012-06-20 16:38:30 -07008409 /*interface type changed update in wiphy structure*/
8410 if(wdev)
8411 {
8412 wdev->iftype = type;
8413 pHddCtx->change_iface = type;
8414 }
8415 else
8416 {
8417 hddLog(VOS_TRACE_LEVEL_ERROR,
8418 "%s: ERROR !!!! Wireless dev is NULL", __func__);
8419 return -EINVAL;
8420 }
8421 goto done;
8422 }
8423
8424 default:
8425 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8426 __func__);
8427 return -EOPNOTSUPP;
8428 }
8429 }
8430 else if ( (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07008431 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Jeff Johnson295189b2012-06-20 16:38:30 -07008432 )
8433 {
8434 switch(type)
8435 {
8436 case NL80211_IFTYPE_STATION:
Jeff Johnson295189b2012-06-20 16:38:30 -07008437 case NL80211_IFTYPE_P2P_CLIENT:
Jeff Johnson295189b2012-06-20 16:38:30 -07008438 case NL80211_IFTYPE_ADHOC:
Deepthi Gowri500fc472014-08-11 19:53:10 +05308439
8440 hdd_stop_adapter( pHddCtx, pAdapter, VOS_TRUE );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308441#ifdef FEATURE_WLAN_TDLS
8442
8443 /* A Mutex Lock is introduced while changing the mode to
8444 * protect the concurrent access for the Adapters by TDLS
8445 * module.
8446 */
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308447 mutex_lock(&pHddCtx->tdls_lock);
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308448#endif
c_hpothu002231a2015-02-05 14:58:51 +05308449 hdd_deinit_adapter( pHddCtx, pAdapter, TRUE);
Jeff Johnson295189b2012-06-20 16:38:30 -07008450 wdev->iftype = type;
Gopichand Nakkalaf527dc62012-12-31 16:35:10 -08008451 //Check for sub-string p2p to confirm its a p2p interface
8452 if (NULL != strstr(ndev->name,"p2p"))
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008453 {
8454 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
8455 WLAN_HDD_P2P_DEVICE : WLAN_HDD_P2P_CLIENT;
8456 }
8457 else
8458 {
8459 pAdapter->device_mode = (type == NL80211_IFTYPE_STATION) ?
Jeff Johnson295189b2012-06-20 16:38:30 -07008460 WLAN_HDD_INFRA_STATION: WLAN_HDD_P2P_CLIENT;
Gopichand Nakkala864d3552012-12-31 16:08:51 -08008461 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008462 hdd_set_conparam(0);
8463 pHddCtx->change_iface = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008464 memset(&pAdapter->sessionCtx, 0, sizeof(pAdapter->sessionCtx));
8465 hdd_set_station_ops( pAdapter->dev );
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308466#ifdef FEATURE_WLAN_TDLS
8467 mutex_unlock(&pHddCtx->tdls_lock);
8468#endif
Sunil Dutt66485cb2013-12-19 19:05:03 +05308469 status = hdd_init_station_mode( pAdapter );
Jeff Johnson295189b2012-06-20 16:38:30 -07008470 if( VOS_STATUS_SUCCESS != status )
8471 return -EOPNOTSUPP;
Jeff Johnsone7245742012-09-05 17:12:55 -07008472 /* In case of JB, for P2P-GO, only change interface will be called,
8473 * This is the right place to enable back bmps_imps()
8474 */
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +05308475 if (pHddCtx->hdd_wlan_suspended)
8476 {
8477 hdd_set_pwrparams(pHddCtx);
8478 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008479 hdd_enable_bmps_imps(pHddCtx);
Jeff Johnson295189b2012-06-20 16:38:30 -07008480 goto done;
8481 case NL80211_IFTYPE_AP:
Jeff Johnson295189b2012-06-20 16:38:30 -07008482 case NL80211_IFTYPE_P2P_GO:
Jeff Johnson295189b2012-06-20 16:38:30 -07008483 wdev->iftype = type;
Jeff Johnson295189b2012-06-20 16:38:30 -07008484 pAdapter->device_mode = (type == NL80211_IFTYPE_AP) ?
8485 WLAN_HDD_SOFTAP : WLAN_HDD_P2P_GO;
Jeff Johnson295189b2012-06-20 16:38:30 -07008486 goto done;
8487 default:
8488 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported interface Type",
8489 __func__);
8490 return -EOPNOTSUPP;
8491
8492 }
8493
8494 }
8495 else
8496 {
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05308497 hddLog(VOS_TRACE_LEVEL_ERROR,"%s: unsupported device mode(%s (%d))",
8498 __func__, hdd_device_modetoString(pAdapter->device_mode),
8499 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07008500 return -EOPNOTSUPP;
8501 }
8502
8503
8504 if(pRoamProfile)
8505 {
8506 if ( LastBSSType != pRoamProfile->BSSType )
8507 {
8508 /*interface type changed update in wiphy structure*/
8509 wdev->iftype = type;
8510
8511 /*the BSS mode changed, We need to issue disconnect
8512 if connected or in IBSS disconnect state*/
8513 if ( hdd_connGetConnectedBssType(
8514 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), &connectedBssType ) ||
8515 ( eCSR_BSS_TYPE_START_IBSS == LastBSSType ) )
8516 {
8517 /*need to issue a disconnect to CSR.*/
8518 INIT_COMPLETION(pAdapter->disconnect_comp_var);
8519 if( eHAL_STATUS_SUCCESS ==
8520 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
8521 pAdapter->sessionId,
8522 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
8523 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308524 ret = wait_for_completion_interruptible_timeout(
8525 &pAdapter->disconnect_comp_var,
8526 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
8527 if (ret <= 0)
8528 {
8529 hddLog(VOS_TRACE_LEVEL_ERROR,
8530 FL("wait on disconnect_comp_var failed %ld"), ret);
8531 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008532 }
8533 }
8534 }
8535 }
8536
8537done:
8538 /*set bitmask based on updated value*/
8539 wlan_hdd_set_concurrency_mode(pHddCtx, pAdapter->device_mode);
Leo Chang6fe1f922013-06-07 19:21:24 -07008540
8541 /* Only STA mode support TM now
8542 * all other mode, TM feature should be disabled */
8543 if ( (pHddCtx->cfg_ini->thermalMitigationEnable) &&
8544 (~VOS_STA & pHddCtx->concurrency_mode) )
8545 {
8546 hddDevTmLevelChangedHandler(pHddCtx->parent_dev, 0);
8547 }
8548
Jeff Johnson295189b2012-06-20 16:38:30 -07008549#ifdef WLAN_BTAMP_FEATURE
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308550 if((NL80211_IFTYPE_STATION == type) && (pHddCtx->concurrency_mode <= 1) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +05308551 (pHddCtx->no_of_open_sessions[WLAN_HDD_INFRA_STATION] <=1))
Jeff Johnson295189b2012-06-20 16:38:30 -07008552 {
8553 //we are ok to do AMP
8554 pHddCtx->isAmpAllowed = VOS_TRUE;
8555 }
8556#endif //WLAN_BTAMP_FEATURE
8557 EXIT();
8558 return 0;
8559}
8560
Mahesh A Saptasagar0e59c472014-04-14 19:17:41 +05308561/*
8562 * FUNCTION: wlan_hdd_cfg80211_change_iface
8563 * wrapper function to protect the actual implementation from SSR.
8564 */
8565int wlan_hdd_cfg80211_change_iface( struct wiphy *wiphy,
8566 struct net_device *ndev,
8567 enum nl80211_iftype type,
8568 u32 *flags,
8569 struct vif_params *params
8570 )
8571{
8572 int ret;
8573
8574 vos_ssr_protect(__func__);
8575 ret = __wlan_hdd_cfg80211_change_iface(wiphy, ndev, type, flags, params);
8576 vos_ssr_unprotect(__func__);
8577
8578 return ret;
8579}
8580
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008581#ifdef FEATURE_WLAN_TDLS
8582static int wlan_hdd_tdls_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308583 struct net_device *dev,
8584#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
8585 const u8 *mac,
8586#else
8587 u8 *mac,
8588#endif
8589 bool update, tCsrStaParams *StaParams)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008590{
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008591 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008592 hddTdlsPeer_t *pTdlsPeer;
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308593 long ret;
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308594 tANI_U16 numCurrTdlsPeers;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308595 hdd_adapter_t *pAdapter;
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05308596 VOS_STATUS status;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008597
8598 ENTER();
8599
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +05308600 if (!dev) {
8601 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Dev pointer is NULL"));
8602 return -EINVAL;
8603 }
8604
8605 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
8606 if (!pAdapter) {
8607 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adapter is NULL"));
8608 return -EINVAL;
8609 }
8610
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308611 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008612 {
8613 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8614 "Invalid arguments");
8615 return -EINVAL;
8616 }
Hoonki Lee27511902013-03-14 18:19:06 -07008617
8618 if ((eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode) ||
8619 (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode))
8620 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308621 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -07008622 "%s: TDLS mode is disabled OR not enabled in FW."
8623 MAC_ADDRESS_STR " Request declined.",
8624 __func__, MAC_ADDR_ARRAY(mac));
8625 return -ENOTSUPP;
8626 }
8627
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008628 if (pHddCtx->isLogpInProgress)
8629 {
8630 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8631 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +05308632 wlan_hdd_tdls_set_link_status(pAdapter,
8633 mac,
8634 eTDLS_LINK_IDLE,
8635 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008636 return -EBUSY;
8637 }
8638
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308639 mutex_lock(&pHddCtx->tdls_lock);
Naresh Jayaram9c6f4462014-02-13 12:20:31 +05308640 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, mac);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008641
8642 if ( NULL == pTdlsPeer ) {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308643 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008644 "%s: " MAC_ADDRESS_STR " (update %d) not exist. return invalid",
8645 __func__, MAC_ADDR_ARRAY(mac), update);
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308646 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008647 return -EINVAL;
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008648 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +05308649 mutex_unlock(&pHddCtx->tdls_lock);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008650
8651 /* in add station, we accept existing valid staId if there is */
8652 if ((0 == update) &&
8653 ((pTdlsPeer->link_status >= eTDLS_LINK_CONNECTING) ||
8654 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008655 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308656 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008657 "%s: " MAC_ADDRESS_STR
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008658 " link_status %d. staId %d. add station ignored.",
8659 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId);
8660 return 0;
8661 }
8662 /* in change station, we accept only when staId is valid */
8663 if ((1 == update) &&
8664 ((pTdlsPeer->link_status > eTDLS_LINK_CONNECTING) ||
8665 (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))))
8666 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308667 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008668 "%s: " MAC_ADDRESS_STR
8669 " link status %d. staId %d. change station %s.",
8670 __func__, MAC_ADDR_ARRAY(mac), pTdlsPeer->link_status, pTdlsPeer->staId,
8671 (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? "ignored" : "declined");
8672 return (TDLS_STA_INDEX_VALID(pTdlsPeer->staId)) ? 0 : -EPERM;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008673 }
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008674
8675 /* when others are on-going, we want to change link_status to idle */
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +05308676 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, mac, TRUE, TRUE))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008677 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008678 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8679 "%s: " MAC_ADDRESS_STR
8680 " TDLS setup is ongoing. Request declined.",
8681 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala05922802013-03-14 12:23:19 -07008682 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008683 }
8684
8685 /* first to check if we reached to maximum supported TDLS peer.
8686 TODO: for now, return -EPERM looks working fine,
8687 but need to check if any other errno fit into this category.*/
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308688 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
8689 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008690 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008691 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8692 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +05308693 " TDLS Max peer already connected. Request declined."
8694 " Num of peers (%d), Max allowed (%d).",
8695 __func__, MAC_ADDR_ARRAY(mac), numCurrTdlsPeers,
8696 HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008697 goto error;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008698 }
8699 else
8700 {
8701 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +05308702 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, mac, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008703 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008704 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008705 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8706 "%s: " MAC_ADDRESS_STR " already connected. Request declined.",
8707 __func__, MAC_ADDR_ARRAY(mac));
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008708 return -EPERM;
8709 }
8710 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008711 if (0 == update)
Atul Mittal115287b2014-07-08 13:26:33 +05308712 wlan_hdd_tdls_set_link_status(pAdapter,
8713 mac,
8714 eTDLS_LINK_CONNECTING,
8715 eTDLS_LINK_SUCCESS);
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008716
Jeff Johnsond75fe012013-04-06 10:53:06 -07008717 /* debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308718 if (NULL != StaParams)
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008719 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308720 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008721 "%s: TDLS Peer Parameters.", __func__);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008722 if(StaParams->htcap_present)
8723 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008725 "ht_capa->cap_info: %0x", StaParams->HTCap.capInfo);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308726 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008727 "ht_capa->extended_capabilities: %0x",
8728 StaParams->HTCap.extendedHtCapInfo);
8729 }
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308730 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008731 "params->capability: %0x",StaParams->capability);
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308732 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson0299d0a2013-10-30 12:37:43 -07008733 "params->ext_capab_len: %0x",StaParams->extn_capability[0]);
Hoonki Lee66b75f32013-04-16 18:30:07 -07008734 if(StaParams->vhtcap_present)
8735 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308736 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee66b75f32013-04-16 18:30:07 -07008737 "rxMcsMap %x rxHighest %x txMcsMap %x txHighest %x",
8738 StaParams->VHTCap.suppMcs.rxMcsMap, StaParams->VHTCap.suppMcs.rxHighest,
8739 StaParams->VHTCap.suppMcs.txMcsMap, StaParams->VHTCap.suppMcs.txHighest);
8740 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008741 {
8742 int i = 0;
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008743 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, "Supported rates:");
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008744 for (i = 0; i < sizeof(StaParams->supported_rates); i++)
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +05308745 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008746 "[%d]: %x ", i, StaParams->supported_rates[i]);
8747 }
Jeff Johnsond75fe012013-04-06 10:53:06 -07008748 } /* end debug code */
Gopichand Nakkala838be5d2013-04-10 22:41:51 +05308749 else if ((1 == update) && (NULL == StaParams))
8750 {
8751 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8752 "%s : update is true, but staParams is NULL. Error!", __func__);
8753 return -EPERM;
8754 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008755
8756 INIT_COMPLETION(pAdapter->tdls_add_station_comp);
8757
8758 if (!update)
8759 {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05308760 /*Before adding sta make sure that device exited from BMPS*/
8761 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
8762 {
8763 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8764 "%s: Adding tdls peer sta. Disable BMPS", __func__);
8765 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
8766 if (status != VOS_STATUS_SUCCESS) {
8767 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
8768 }
8769 }
8770
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308771 ret = sme_AddTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008772 pAdapter->sessionId, mac);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308773 if (ret != eHAL_STATUS_SUCCESS) {
Ganesh Kondabattinif065c1f2015-08-05 23:05:23 +05308774 hddLog(VOS_TRACE_LEVEL_ERROR,
8775 FL("Failed to add TDLS peer STA. Enable Bmps"));
8776 wlan_hdd_tdls_check_bmps(pAdapter);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308777 return -EPERM;
8778 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008779 }
8780 else
8781 {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308782 ret = sme_ChangeTdlsPeerSta(WLAN_HDD_GET_HAL_CTX(pAdapter),
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008783 pAdapter->sessionId, mac, StaParams);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +05308784 if (ret != eHAL_STATUS_SUCCESS) {
8785 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to change TDLS peer STA params"));
8786 return -EPERM;
8787 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008788 }
8789
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308790 ret = wait_for_completion_interruptible_timeout(&pAdapter->tdls_add_station_comp,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008791 msecs_to_jiffies(WAIT_TIME_TDLS_ADD_STA));
8792
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308793 if (ret <= 0)
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008794 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008795 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308796 "%s: timeout waiting for tdls add station indication %ld",
8797 __func__, ret);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008798 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008799 }
c_hpothu6ff1c3c2013-10-01 19:01:57 +05308800
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008801 if ( eHAL_STATUS_SUCCESS != pAdapter->tdlsAddStaStatus)
8802 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -07008803 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008804 "%s: Add Station is unsucessful", __func__);
Gopichand Nakkala34d1b062013-03-19 15:28:33 -07008805 return -EPERM;
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008806 }
8807
8808 return 0;
Gopichand Nakkala05922802013-03-14 12:23:19 -07008809
8810error:
Atul Mittal115287b2014-07-08 13:26:33 +05308811 wlan_hdd_tdls_set_link_status(pAdapter,
8812 mac,
8813 eTDLS_LINK_IDLE,
8814 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkala05922802013-03-14 12:23:19 -07008815 return -EPERM;
8816
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008817}
8818#endif
8819
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05308820static int __wlan_hdd_change_station(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07008821 struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308822#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
8823 const u8 *mac,
8824#else
Jeff Johnson295189b2012-06-20 16:38:30 -07008825 u8 *mac,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308826#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07008827 struct station_parameters *params)
8828{
8829 VOS_STATUS status = VOS_STATUS_SUCCESS;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308830 hdd_adapter_t *pAdapter;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308831 hdd_context_t *pHddCtx;
8832 hdd_station_ctx_t *pHddStaCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07008833 v_MACADDR_t STAMacAddress;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308834 int ret = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008835#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008836 tCsrStaParams StaParams = {0};
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008837 tANI_U8 isBufSta = 0;
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308838 tANI_U8 isOffChannelSupported = 0;
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008839#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07008840
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308841 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05308842
Mahesh A Saptasagar74088392015-02-05 17:22:09 +05308843 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308844 if ((NULL == pAdapter))
8845 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05308846 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05308847 "invalid adapter ");
8848 return -EINVAL;
8849 }
8850
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05308851 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
8852 TRACE_CODE_HDD_CHANGE_STATION,
8853 pAdapter->sessionId, params->listen_interval));
Gopichand Nakkala29149562013-05-10 21:43:41 +05308854 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala29149562013-05-10 21:43:41 +05308855
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308856 ret = wlan_hdd_validate_context(pHddCtx);
8857 if (0 != ret)
Gopichand Nakkala29149562013-05-10 21:43:41 +05308858 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308859 return ret;
Gopichand Nakkala29149562013-05-10 21:43:41 +05308860 }
8861
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308862 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
8863
8864 if (NULL == pHddStaCtx)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008865 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05308866 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
8867 "invalid HDD station context");
8868 return -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07008869 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008870 vos_mem_copy(STAMacAddress.bytes, mac, sizeof(v_MACADDR_t));
8871
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008872 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
8873 || (pAdapter->device_mode == WLAN_HDD_P2P_GO))
Jeff Johnson295189b2012-06-20 16:38:30 -07008874 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008875 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
Jeff Johnson295189b2012-06-20 16:38:30 -07008876 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05308877 status = hdd_softap_change_STA_state( pAdapter, &STAMacAddress,
Jeff Johnson295189b2012-06-20 16:38:30 -07008878 WLANTL_STA_AUTHENTICATED);
8879
Gopichand Nakkala29149562013-05-10 21:43:41 +05308880 if (status != VOS_STATUS_SUCCESS)
8881 {
8882 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
8883 "%s: Not able to change TL state to AUTHENTICATED", __func__);
8884 return -EINVAL;
8885 }
Jeff Johnson295189b2012-06-20 16:38:30 -07008886 }
8887 }
Hoonki Leea6d49be2013-04-05 09:43:25 -07008888 else if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
8889 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)) {
Gopichand Nakkala29149562013-05-10 21:43:41 +05308890#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008891 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
8892 StaParams.capability = params->capability;
8893 StaParams.uapsd_queues = params->uapsd_queues;
8894 StaParams.max_sp = params->max_sp;
8895
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308896 /* Convert (first channel , number of channels) tuple to
8897 * the total list of channels. This goes with the assumption
8898 * that if the first channel is < 14, then the next channels
8899 * are an incremental of 1 else an incremental of 4 till the number
8900 * of channels.
8901 */
8902 if (0 != params->supported_channels_len) {
8903 int i = 0,j = 0,k = 0, no_of_channels = 0 ;
8904 for ( i = 0 ; i < params->supported_channels_len ; i+=2)
8905 {
8906 int wifi_chan_index;
8907 StaParams.supported_channels[j] = params->supported_channels[i];
8908 wifi_chan_index =
8909 ((StaParams.supported_channels[j] <= HDD_CHANNEL_14 ) ? 1 : 4 );
8910 no_of_channels = params->supported_channels[i+1];
8911 for(k=1; k <= no_of_channels; k++)
8912 {
8913 StaParams.supported_channels[j+1] =
8914 StaParams.supported_channels[j] + wifi_chan_index;
8915 j+=1;
8916 }
8917 }
8918 StaParams.supported_channels_len = j;
8919 }
8920 vos_mem_copy(StaParams.supported_oper_classes,
8921 params->supported_oper_classes,
8922 params->supported_oper_classes_len);
8923 StaParams.supported_oper_classes_len =
8924 params->supported_oper_classes_len;
8925
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008926 if (0 != params->ext_capab_len)
8927 vos_mem_copy(StaParams.extn_capability, params->ext_capab,
8928 sizeof(StaParams.extn_capability));
8929
8930 if (NULL != params->ht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008931 {
8932 StaParams.htcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008933 vos_mem_copy(&StaParams.HTCap, params->ht_capa, sizeof(tSirHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008934 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008935
8936 StaParams.supported_rates_len = params->supported_rates_len;
8937
8938 /* Note : The Maximum sizeof supported_rates sent by the Supplicant is 32.
8939 * The supported_rates array , for all the structures propogating till Add Sta
8940 * to the firmware has to be modified , if the supplicant (ieee80211) is
8941 * modified to send more rates.
8942 */
8943
8944 /* To avoid Data Currption , set to max length to SIR_MAC_MAX_SUPP_RATES
8945 */
8946 if (StaParams.supported_rates_len > SIR_MAC_MAX_SUPP_RATES)
8947 StaParams.supported_rates_len = SIR_MAC_MAX_SUPP_RATES;
8948
8949 if (0 != StaParams.supported_rates_len) {
8950 int i = 0;
8951 vos_mem_copy(StaParams.supported_rates, params->supported_rates,
8952 StaParams.supported_rates_len);
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008953 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008954 "Supported Rates with Length %d", StaParams.supported_rates_len);
8955 for (i=0; i < StaParams.supported_rates_len; i++)
Hoonki Lee5305c3a2013-04-29 23:28:59 -07008956 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008957 "[%d]: %0x", i, StaParams.supported_rates[i]);
8958 }
8959
8960 if (NULL != params->vht_capa)
Hoonki Lee66b75f32013-04-16 18:30:07 -07008961 {
8962 StaParams.vhtcap_present = 1;
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008963 vos_mem_copy(&StaParams.VHTCap, params->vht_capa, sizeof(tSirVHTCap));
Hoonki Lee66b75f32013-04-16 18:30:07 -07008964 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -07008965
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008966 if (0 != params->ext_capab_len ) {
8967 /*Define A Macro : TODO Sunil*/
8968 if ((1<<4) & StaParams.extn_capability[3]) {
8969 isBufSta = 1;
8970 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308971 /* TDLS Channel Switching Support */
8972 if ((1<<6) & StaParams.extn_capability[3]) {
8973 isOffChannelSupported = 1;
8974 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008975 }
Naresh Jayaram3180aa42014-02-12 21:47:26 +05308976 status = wlan_hdd_tdls_set_peer_caps( pAdapter, mac,
8977 &StaParams, isBufSta,
8978 isOffChannelSupported);
8979
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +05308980 if (VOS_STATUS_SUCCESS != status) {
8981 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8982 "%s: wlan_hdd_tdls_set_peer_caps failed!", __func__);
8983 return -EINVAL;
8984 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -08008985 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 1, &StaParams);
8986
8987 if (VOS_STATUS_SUCCESS != status) {
8988 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
8989 "%s: sme_ChangeTdlsPeerSta failed!", __func__);
8990 return -EINVAL;
8991 }
8992 }
Gopichand Nakkalab0856222013-03-12 22:39:05 -07008993#endif
Gopichand Nakkala6239acd2013-06-14 14:48:00 +05308994 }
Jeff Johnsone7245742012-09-05 17:12:55 -07008995 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07008996 return status;
8997}
8998
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05308999#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
9000static int wlan_hdd_change_station(struct wiphy *wiphy,
9001 struct net_device *dev,
9002 const u8 *mac,
9003 struct station_parameters *params)
9004#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309005static int wlan_hdd_change_station(struct wiphy *wiphy,
9006 struct net_device *dev,
9007 u8 *mac,
9008 struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +05309009#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309010{
9011 int ret;
9012
9013 vos_ssr_protect(__func__);
9014 ret = __wlan_hdd_change_station(wiphy, dev, mac, params);
9015 vos_ssr_unprotect(__func__);
9016
9017 return ret;
9018}
9019
Jeff Johnson295189b2012-06-20 16:38:30 -07009020/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309021 * FUNCTION: __wlan_hdd_cfg80211_add_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009022 * This function is used to initialize the key information
9023 */
9024#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309025static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009026 struct net_device *ndev,
9027 u8 key_index, bool pairwise,
9028 const u8 *mac_addr,
9029 struct key_params *params
9030 )
9031#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309032static int __wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009033 struct net_device *ndev,
9034 u8 key_index, const u8 *mac_addr,
9035 struct key_params *params
9036 )
9037#endif
9038{
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009039 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -07009040 tCsrRoamSetKey setKey;
9041 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309042 int status;
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009043 v_U32_t roamId= 0xFF;
9044 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009045 hdd_hostapd_state_t *pHostapdState;
9046 VOS_STATUS vos_status;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009047 eHalStatus halStatus;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309048 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009049
9050 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309051
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309052 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9053 TRACE_CODE_HDD_CFG80211_ADD_KEY,
9054 pAdapter->sessionId, params->key_len));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309055 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9056 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309057 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009058 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309059 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009060 }
9061
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309062 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9063 __func__, hdd_device_modetoString(pAdapter->device_mode),
9064 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -07009065
9066 if (CSR_MAX_NUM_KEY <= key_index)
9067 {
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009068 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009069 key_index);
9070
9071 return -EINVAL;
9072 }
9073
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009074 if (CSR_MAX_KEY_LEN < params->key_len)
9075 {
9076 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key length %d", __func__,
9077 params->key_len);
9078
9079 return -EINVAL;
9080 }
9081
9082 hddLog(VOS_TRACE_LEVEL_INFO,
9083 "%s: called with key index = %d & key length %d",
9084 __func__, key_index, params->key_len);
Jeff Johnson295189b2012-06-20 16:38:30 -07009085
9086 /*extract key idx, key len and key*/
9087 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9088 setKey.keyId = key_index;
9089 setKey.keyLength = params->key_len;
9090 vos_mem_copy(&setKey.Key[0],params->key, params->key_len);
9091
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009092 switch (params->cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -07009093 {
9094 case WLAN_CIPHER_SUITE_WEP40:
9095 setKey.encType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
9096 break;
9097
9098 case WLAN_CIPHER_SUITE_WEP104:
9099 setKey.encType = eCSR_ENCRYPT_TYPE_WEP104_STATICKEY;
9100 break;
9101
9102 case WLAN_CIPHER_SUITE_TKIP:
9103 {
9104 u8 *pKey = &setKey.Key[0];
9105 setKey.encType = eCSR_ENCRYPT_TYPE_TKIP;
9106
9107 vos_mem_zero(pKey, CSR_MAX_KEY_LEN);
9108
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009109 /*Supplicant sends the 32bytes key in this order
Jeff Johnson295189b2012-06-20 16:38:30 -07009110
9111 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009112 | Tk1 |TX-MIC | RX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009113 |--------------|----------|----------|
9114 <---16bytes---><--8bytes--><--8bytes-->
9115
9116 */
9117 /*Sme expects the 32 bytes key to be in the below order
9118
9119 |--------------|----------|----------|
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009120 | Tk1 |RX-MIC | TX Mic |
Jeff Johnson295189b2012-06-20 16:38:30 -07009121 |--------------|----------|----------|
9122 <---16bytes---><--8bytes--><--8bytes-->
9123 */
9124 /* Copy the Temporal Key 1 (TK1) */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009125 vos_mem_copy(pKey, params->key, 16);
Jeff Johnson295189b2012-06-20 16:38:30 -07009126
9127 /*Copy the rx mic first*/
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009128 vos_mem_copy(&pKey[16], &params->key[24], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009129
9130 /*Copy the tx mic */
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009131 vos_mem_copy(&pKey[24], &params->key[16], 8);
Jeff Johnson295189b2012-06-20 16:38:30 -07009132
9133
9134 break;
9135 }
9136
9137 case WLAN_CIPHER_SUITE_CCMP:
9138 setKey.encType = eCSR_ENCRYPT_TYPE_AES;
9139 break;
9140
9141#ifdef FEATURE_WLAN_WAPI
9142 case WLAN_CIPHER_SUITE_SMS4:
9143 {
9144 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9145 wlan_hdd_cfg80211_set_key_wapi(pAdapter, key_index, mac_addr,
9146 params->key, params->key_len);
9147 return 0;
9148 }
9149#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009150
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -08009151#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -07009152 case WLAN_CIPHER_SUITE_KRK:
9153 setKey.encType = eCSR_ENCRYPT_TYPE_KRK;
9154 break;
9155#endif
Chet Lanctot186b5732013-03-18 10:26:30 -07009156
9157#ifdef WLAN_FEATURE_11W
9158 case WLAN_CIPHER_SUITE_AES_CMAC:
9159 setKey.encType = eCSR_ENCRYPT_TYPE_AES_CMAC;
Chet Lanctot3b5158a2013-03-31 16:45:21 -07009160 break;
Chet Lanctot186b5732013-03-18 10:26:30 -07009161#endif
9162
Jeff Johnson295189b2012-06-20 16:38:30 -07009163 default:
Jeff Johnson0299d0a2013-10-30 12:37:43 -07009164 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unsupported cipher type %u",
Jeff Johnson295189b2012-06-20 16:38:30 -07009165 __func__, params->cipher);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309166 status = -EOPNOTSUPP;
9167 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009168 }
9169
9170 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: encryption type %d",
9171 __func__, setKey.encType);
9172
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009173 if (
Jeff Johnson295189b2012-06-20 16:38:30 -07009174#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9175 (!pairwise)
9176#else
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009177 (!mac_addr || is_broadcast_ether_addr(mac_addr))
Jeff Johnson295189b2012-06-20 16:38:30 -07009178#endif
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009179 )
9180 {
9181 /* set group key*/
9182 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9183 "%s- %d: setting Broadcast key",
9184 __func__, __LINE__);
9185 setKey.keyDirection = eSIR_RX_ONLY;
9186 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9187 }
9188 else
9189 {
9190 /* set pairwise key*/
9191 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9192 "%s- %d: setting pairwise key",
9193 __func__, __LINE__);
9194 setKey.keyDirection = eSIR_TX_RX;
9195 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9196 }
9197 if ((WLAN_HDD_IBSS == pAdapter->device_mode) && !pairwise)
9198 {
9199 setKey.keyDirection = eSIR_TX_RX;
9200 /*Set the group key*/
9201 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9202 pAdapter->sessionId, &setKey, &roamId );
Jeff Johnson295189b2012-06-20 16:38:30 -07009203
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009204 if ( 0 != status )
9205 {
9206 hddLog(VOS_TRACE_LEVEL_ERROR,
9207 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309208 status = -EINVAL;
9209 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009210 }
9211 /*Save the keys here and call sme_RoamSetKey for setting
9212 the PTK after peer joins the IBSS network*/
9213 vos_mem_copy(&pAdapter->sessionCtx.station.ibss_enc_key,
9214 &setKey, sizeof(tCsrRoamSetKey));
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309215 goto end;
Shailender Karmuchi642e9812013-05-30 14:34:49 -07009216 }
Gopichand Nakkala29149562013-05-10 21:43:41 +05309217 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP) ||
9218 (pAdapter->device_mode == WLAN_HDD_P2P_GO))
9219 {
Jeff Johnson295189b2012-06-20 16:38:30 -07009220 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009221 if( pHostapdState->bssState == BSS_START )
9222 {
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009223 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9224 vos_status = wlan_hdd_check_ula_done(pAdapter);
9225
9226 if ( vos_status != VOS_STATUS_SUCCESS )
9227 {
9228 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9229 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9230 __LINE__, vos_status );
9231
9232 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9233
9234 status = -EINVAL;
9235 goto end;
9236 }
9237
Jeff Johnson295189b2012-06-20 16:38:30 -07009238 status = WLANSAP_SetKeySta( pVosContext, &setKey);
9239
9240 if ( status != eHAL_STATUS_SUCCESS )
9241 {
9242 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9243 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9244 __LINE__, status );
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309245 status = -EINVAL;
9246 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009247 }
9248 }
9249
9250 /* Saving WEP keys */
9251 else if( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == setKey.encType ||
9252 eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == setKey.encType )
9253 {
9254 //Save the wep key in ap context. Issue setkey after the BSS is started.
9255 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9256 vos_mem_copy(&pAPCtx->wepKey[key_index], &setKey, sizeof(tCsrRoamSetKey));
9257 }
9258 else
9259 {
9260 //Save the key in ap context. Issue setkey after the BSS is started.
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009261 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -07009262 vos_mem_copy(&pAPCtx->groupKey, &setKey, sizeof(tCsrRoamSetKey));
9263 }
9264 }
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009265 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) ||
9266 (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT) )
Jeff Johnson295189b2012-06-20 16:38:30 -07009267 {
9268 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9269 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9270
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309271#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9272 if (!pairwise)
9273#else
9274 if (!mac_addr || is_broadcast_ether_addr(mac_addr))
9275#endif
9276 {
9277 /* set group key*/
9278 if (pHddStaCtx->roam_info.deferKeyComplete)
9279 {
9280 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
9281 "%s- %d: Perform Set key Complete",
9282 __func__, __LINE__);
9283 hdd_PerformRoamSetKeyComplete(pAdapter);
9284 }
9285 }
9286
Jeff Johnson295189b2012-06-20 16:38:30 -07009287 pWextState->roamProfile.Keys.KeyLength[key_index] = (u8)params->key_len;
9288
Venkata Prathyusha Kuntupalliee2ce712013-01-17 14:09:24 -08009289 pWextState->roamProfile.Keys.defaultIndex = key_index;
9290
9291
Jeff Johnsonf77ef0a2013-03-27 09:29:14 -07009292 vos_mem_copy(&pWextState->roamProfile.Keys.KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009293 params->key, params->key_len);
9294
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309295
Jeff Johnson295189b2012-06-20 16:38:30 -07009296 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9297
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309298 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009299 "%s: set key for peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309300 __func__, setKey.peerMac[0], setKey.peerMac[1],
9301 setKey.peerMac[2], setKey.peerMac[3],
9302 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009303 setKey.keyDirection);
9304
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009305 vos_status = wlan_hdd_check_ula_done(pAdapter);
Nirav Shah4f765af2015-01-21 19:51:30 +05309306
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009307 if ( vos_status != VOS_STATUS_SUCCESS )
9308 {
9309 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009310 "[%4d] wlan_hdd_check_ula_done returned ERROR status= %d",
9311 __LINE__, vos_status );
9312
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009313 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Jeff Johnson295189b2012-06-20 16:38:30 -07009314
Nirav Shah4b53d4b2015-05-08 05:35:00 -07009315 status = -EINVAL;
9316 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009317
9318 }
9319
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009320#ifdef WLAN_FEATURE_VOWIFI_11R
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309321 /* The supplicant may attempt to set the PTK once pre-authentication
9322 is done. Save the key in the UMAC and include it in the ADD BSS
9323 request */
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009324 halStatus = sme_FTUpdateKey( WLAN_HDD_GET_HAL_CTX(pAdapter), &setKey);
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309325 if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_SUCCESS )
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009326 {
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309327 hddLog(VOS_TRACE_LEVEL_INFO_MED,
9328 "%s: Update PreAuth Key success", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309329 status = 0;
9330 goto end;
Gopichand Nakkala3d295922013-05-07 16:19:14 +05309331 }
9332 else if ( halStatus == eHAL_STATUS_FT_PREAUTH_KEY_FAILED )
9333 {
9334 hddLog(VOS_TRACE_LEVEL_ERROR,
9335 "%s: Update PreAuth Key failed", __func__);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309336 status = -EINVAL;
9337 goto end;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -07009338 }
9339#endif /* WLAN_FEATURE_VOWIFI_11R */
Jeff Johnson295189b2012-06-20 16:38:30 -07009340
9341 /* issue set key request to SME*/
9342 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
9343 pAdapter->sessionId, &setKey, &roamId );
9344
9345 if ( 0 != status )
9346 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309347 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009348 "%s: sme_RoamSetKey failed, returned %d", __func__, status);
9349 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309350 status = -EINVAL;
9351 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009352 }
9353
9354
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309355 /* in case of IBSS as there was no information available about WEP keys during
9356 * IBSS join, group key intialized with NULL key, so re-initialize group key
Jeff Johnson295189b2012-06-20 16:38:30 -07009357 * with correct value*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309358 if ( (eCSR_BSS_TYPE_START_IBSS == pWextState->roamProfile.BSSType) &&
9359 !( ( IW_AUTH_KEY_MGMT_802_1X
9360 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X))
Jeff Johnson295189b2012-06-20 16:38:30 -07009361 && (eCSR_AUTH_TYPE_OPEN_SYSTEM == pHddStaCtx->conn_info.authType)
9362 )
9363 &&
9364 ( (WLAN_CIPHER_SUITE_WEP40 == params->cipher)
9365 || (WLAN_CIPHER_SUITE_WEP104 == params->cipher)
9366 )
9367 )
9368 {
9369 setKey.keyDirection = eSIR_RX_ONLY;
9370 vos_mem_copy(setKey.peerMac,groupmacaddr,WNI_CFG_BSSID_LEN);
9371
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309372 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009373 "%s: set key peerMac %2x:%2x:%2x:%2x:%2x:%2x, direction %d",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309374 __func__, setKey.peerMac[0], setKey.peerMac[1],
9375 setKey.peerMac[2], setKey.peerMac[3],
9376 setKey.peerMac[4], setKey.peerMac[5],
Jeff Johnson295189b2012-06-20 16:38:30 -07009377 setKey.keyDirection);
9378
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309379 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009380 pAdapter->sessionId, &setKey, &roamId );
9381
9382 if ( 0 != status )
9383 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309384 hddLog(VOS_TRACE_LEVEL_ERROR,
9385 "%s: sme_RoamSetKey failed for group key (IBSS), returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009386 __func__, status);
9387 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309388 status = -EINVAL;
9389 goto end;
Jeff Johnson295189b2012-06-20 16:38:30 -07009390 }
9391 }
9392 }
9393
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309394end:
9395 /* Need to clear any trace of key value in the memory.
9396 * Thus zero out the memory even though it is local
9397 * variable.
9398 */
9399 vos_mem_zero(&setKey, sizeof(setKey));
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309400 EXIT();
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +05309401 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -07009402}
9403
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309404#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9405static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9406 struct net_device *ndev,
9407 u8 key_index, bool pairwise,
9408 const u8 *mac_addr,
9409 struct key_params *params
9410 )
9411#else
9412static int wlan_hdd_cfg80211_add_key( struct wiphy *wiphy,
9413 struct net_device *ndev,
9414 u8 key_index, const u8 *mac_addr,
9415 struct key_params *params
9416 )
9417#endif
9418{
9419 int ret;
9420 vos_ssr_protect(__func__);
9421#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9422 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, pairwise,
9423 mac_addr, params);
9424#else
9425 ret = __wlan_hdd_cfg80211_add_key(wiphy, ndev, key_index, mac_addr,
9426 params);
9427#endif
9428 vos_ssr_unprotect(__func__);
9429
9430 return ret;
9431}
9432
Jeff Johnson295189b2012-06-20 16:38:30 -07009433/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309434 * FUNCTION: __wlan_hdd_cfg80211_get_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009435 * This function is used to get the key information
9436 */
9437#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309438static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309439 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009440 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309441 u8 key_index, bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009442 const u8 *mac_addr, void *cookie,
9443 void (*callback)(void *cookie, struct key_params*)
9444 )
9445#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309446static int __wlan_hdd_cfg80211_get_key(
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309447 struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009448 struct net_device *ndev,
9449 u8 key_index, const u8 *mac_addr, void *cookie,
9450 void (*callback)(void *cookie, struct key_params*)
9451 )
9452#endif
9453{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309454 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309455 hdd_wext_state_t *pWextState = NULL;
9456 tCsrRoamProfile *pRoamProfile = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009457 struct key_params params;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309458 hdd_context_t *pHddCtx;
9459 int ret = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -07009460
9461 ENTER();
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309462
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309463 if (NULL == pAdapter)
9464 {
9465 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9466 "%s: HDD adapter is Null", __func__);
9467 return -ENODEV;
9468 }
9469
9470 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9471 ret = wlan_hdd_validate_context(pHddCtx);
9472 if (0 != ret)
9473 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +05309474 return ret;
9475 }
9476
9477 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9478 pRoamProfile = &(pWextState->roamProfile);
9479
Sushant Kaushik8bc7df22014-04-09 17:55:29 +05309480 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
9481 __func__, hdd_device_modetoString(pAdapter->device_mode),
9482 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309483
Jeff Johnson295189b2012-06-20 16:38:30 -07009484 memset(&params, 0, sizeof(params));
9485
9486 if (CSR_MAX_NUM_KEY <= key_index)
9487 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +05309488 hddLog(VOS_TRACE_LEVEL_ERROR, FL("invalid key index %d"), key_index);
Jeff Johnson295189b2012-06-20 16:38:30 -07009489 return -EINVAL;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309490 }
Jeff Johnson295189b2012-06-20 16:38:30 -07009491
9492 switch(pRoamProfile->EncryptionType.encryptionType[0])
9493 {
9494 case eCSR_ENCRYPT_TYPE_NONE:
9495 params.cipher = IW_AUTH_CIPHER_NONE;
9496 break;
9497
9498 case eCSR_ENCRYPT_TYPE_WEP40_STATICKEY:
9499 case eCSR_ENCRYPT_TYPE_WEP40:
9500 params.cipher = WLAN_CIPHER_SUITE_WEP40;
9501 break;
9502
9503 case eCSR_ENCRYPT_TYPE_WEP104_STATICKEY:
9504 case eCSR_ENCRYPT_TYPE_WEP104:
9505 params.cipher = WLAN_CIPHER_SUITE_WEP104;
9506 break;
9507
9508 case eCSR_ENCRYPT_TYPE_TKIP:
9509 params.cipher = WLAN_CIPHER_SUITE_TKIP;
9510 break;
9511
9512 case eCSR_ENCRYPT_TYPE_AES:
9513 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
9514 break;
9515
9516 default:
9517 params.cipher = IW_AUTH_CIPHER_NONE;
9518 break;
9519 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309520
c_hpothuaaf19692014-05-17 17:01:48 +05309521 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9522 TRACE_CODE_HDD_CFG80211_GET_KEY,
9523 pAdapter->sessionId, params.cipher));
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309524
Jeff Johnson295189b2012-06-20 16:38:30 -07009525 params.key_len = pRoamProfile->Keys.KeyLength[key_index];
9526 params.seq_len = 0;
9527 params.seq = NULL;
9528 params.key = &pRoamProfile->Keys.KeyMaterial[key_index][0];
9529 callback(cookie, &params);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309530 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009531 return 0;
9532}
9533
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309534#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9535static int wlan_hdd_cfg80211_get_key(
9536 struct wiphy *wiphy,
9537 struct net_device *ndev,
9538 u8 key_index, bool pairwise,
9539 const u8 *mac_addr, void *cookie,
9540 void (*callback)(void *cookie, struct key_params*)
9541 )
9542#else
9543static int wlan_hdd_cfg80211_get_key(
9544 struct wiphy *wiphy,
9545 struct net_device *ndev,
9546 u8 key_index, const u8 *mac_addr, void *cookie,
9547 void (*callback)(void *cookie, struct key_params*)
9548 )
9549#endif
9550{
9551 int ret;
9552
9553 vos_ssr_protect(__func__);
9554#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9555 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, pairwise,
9556 mac_addr, cookie, callback);
9557#else
9558 ret = __wlan_hdd_cfg80211_get_key(wiphy, ndev, key_index, mac_addr,
9559 callback);
9560#endif
9561 vos_ssr_unprotect(__func__);
9562
9563 return ret;
9564}
9565
Jeff Johnson295189b2012-06-20 16:38:30 -07009566/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309567 * FUNCTION: __wlan_hdd_cfg80211_del_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009568 * This function is used to delete the key information
9569 */
9570#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309571static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009572 struct net_device *ndev,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309573 u8 key_index,
9574 bool pairwise,
Jeff Johnson295189b2012-06-20 16:38:30 -07009575 const u8 *mac_addr
9576 )
9577#else
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309578static int __wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009579 struct net_device *ndev,
9580 u8 key_index,
9581 const u8 *mac_addr
9582 )
9583#endif
9584{
9585 int status = 0;
9586
9587 //This code needs to be revisited. There is sme_removeKey API, we should
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309588 //plan to use that. After the change to use correct index in setkey,
Jeff Johnson295189b2012-06-20 16:38:30 -07009589 //it is observed that this is invalidating peer
9590 //key index whenever re-key is done. This is affecting data link.
9591 //It should be ok to ignore del_key.
9592#if 0
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309593 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
9594 v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
Jeff Johnson295189b2012-06-20 16:38:30 -07009595 u8 groupmacaddr[WNI_CFG_BSSID_LEN] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
9596 tCsrRoamSetKey setKey;
9597 v_U32_t roamId= 0xFF;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309598
Jeff Johnson295189b2012-06-20 16:38:30 -07009599 ENTER();
9600
9601 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: device_mode = %d\n",
9602 __func__,pAdapter->device_mode);
9603
9604 if (CSR_MAX_NUM_KEY <= key_index)
9605 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309606 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009607 key_index);
9608
9609 return -EINVAL;
9610 }
9611
9612 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9613 setKey.keyId = key_index;
9614
9615 if (mac_addr)
9616 vos_mem_copy(setKey.peerMac, mac_addr,WNI_CFG_BSSID_LEN);
9617 else
9618 vos_mem_copy(setKey.peerMac, groupmacaddr, WNI_CFG_BSSID_LEN);
9619
9620 setKey.encType = eCSR_ENCRYPT_TYPE_NONE;
9621
9622 if ((pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -07009623 || (pAdapter->device_mode == WLAN_HDD_P2P_GO)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309624 )
9625 {
9626
9627 hdd_hostapd_state_t *pHostapdState =
Jeff Johnson295189b2012-06-20 16:38:30 -07009628 WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
9629 if( pHostapdState->bssState == BSS_START)
9630 {
9631 status = WLANSAP_SetKeySta( pVosContext, &setKey);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309632
Jeff Johnson295189b2012-06-20 16:38:30 -07009633 if ( status != eHAL_STATUS_SUCCESS )
9634 {
9635 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9636 "[%4d] WLANSAP_SetKeySta returned ERROR status= %d",
9637 __LINE__, status );
9638 }
9639 }
9640 }
9641 else if ( (pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309642 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Jeff Johnson295189b2012-06-20 16:38:30 -07009643 )
9644 {
9645 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9646
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309647 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_SETTING_KEY;
9648
9649 hddLog(VOS_TRACE_LEVEL_INFO_MED,
Jeff Johnson295189b2012-06-20 16:38:30 -07009650 "%s: delete key for peerMac %2x:%2x:%2x:%2x:%2x:%2x",
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309651 __func__, setKey.peerMac[0], setKey.peerMac[1],
9652 setKey.peerMac[2], setKey.peerMac[3],
Jeff Johnson295189b2012-06-20 16:38:30 -07009653 setKey.peerMac[4], setKey.peerMac[5]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309654 if(pAdapter->sessionCtx.station.conn_info.connState ==
9655 eConnectionState_Associated)
Jeff Johnson295189b2012-06-20 16:38:30 -07009656 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309657 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009658 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309659
Jeff Johnson295189b2012-06-20 16:38:30 -07009660 if ( 0 != status )
9661 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309662 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -07009663 "%s: sme_RoamSetKey failure, returned %d",
9664 __func__, status);
9665 pHddStaCtx->roam_info.roamingState = HDD_ROAM_STATE_NONE;
9666 return -EINVAL;
9667 }
9668 }
9669 }
9670#endif
Jeff Johnsone7245742012-09-05 17:12:55 -07009671 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009672 return status;
9673}
9674
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +05309675#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9676static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9677 struct net_device *ndev,
9678 u8 key_index,
9679 bool pairwise,
9680 const u8 *mac_addr
9681 )
9682#else
9683static int wlan_hdd_cfg80211_del_key( struct wiphy *wiphy,
9684 struct net_device *ndev,
9685 u8 key_index,
9686 const u8 *mac_addr
9687 )
9688#endif
9689{
9690 int ret;
9691
9692 vos_ssr_protect(__func__);
9693#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9694 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, pairwise,
9695 mac_addr);
9696#else
9697 ret = __wlan_hdd_cfg80211_del_key(wiphy, ndev, key_index, mac_addr);
9698#endif
9699 vos_ssr_unprotect(__func__);
9700
9701 return ret;
9702}
9703
Jeff Johnson295189b2012-06-20 16:38:30 -07009704/*
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309705 * FUNCTION: __wlan_hdd_cfg80211_set_default_key
Jeff Johnson295189b2012-06-20 16:38:30 -07009706 * This function is used to set the default tx key index
9707 */
9708#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309709static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009710 struct net_device *ndev,
9711 u8 key_index,
9712 bool unicast, bool multicast)
9713#else
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309714static int __wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -07009715 struct net_device *ndev,
9716 u8 key_index)
9717#endif
9718{
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309719 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309720 int status;
Gopichand Nakkala29149562013-05-10 21:43:41 +05309721 hdd_wext_state_t *pWextState;
9722 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309723 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -07009724
9725 ENTER();
9726
Gopichand Nakkala29149562013-05-10 21:43:41 +05309727 if ((NULL == pAdapter))
9728 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +05309729 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala29149562013-05-10 21:43:41 +05309730 "invalid adapter");
9731 return -EINVAL;
9732 }
9733
Sushant Kaushik4b7cb302014-01-06 17:45:01 +05309734 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
9735 TRACE_CODE_HDD_CFG80211_SET_DEFAULT_KEY,
9736 pAdapter->sessionId, key_index));
9737
Gopichand Nakkala29149562013-05-10 21:43:41 +05309738 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
9739 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
9740
9741 if ((NULL == pWextState) || (NULL == pHddStaCtx))
9742 {
9743 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
9744 "invalid Wext state or HDD context");
9745 return -EINVAL;
9746 }
9747
Arif Hussain6d2a3322013-11-17 19:50:10 -08009748 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %d key_index = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009749 __func__,pAdapter->device_mode, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309750
Jeff Johnson295189b2012-06-20 16:38:30 -07009751 if (CSR_MAX_NUM_KEY <= key_index)
9752 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309753 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid key index %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009754 key_index);
9755
9756 return -EINVAL;
9757 }
9758
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309759 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9760 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309761 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009762 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +05309763 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -07009764 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309765
Jeff Johnson295189b2012-06-20 16:38:30 -07009766 if ((pAdapter->device_mode == WLAN_HDD_INFRA_STATION)
Jeff Johnson295189b2012-06-20 16:38:30 -07009767 || (pAdapter->device_mode == WLAN_HDD_P2P_CLIENT)
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309768 )
Jeff Johnson295189b2012-06-20 16:38:30 -07009769 {
Gopichand Nakkala29149562013-05-10 21:43:41 +05309770 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
Arif Hussain6943f522013-11-04 20:10:10 -08009771 pHddStaCtx->conn_info.ucEncryptionType) &&
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309772 (eCSR_ENCRYPT_TYPE_AES !=
Arif Hussain6943f522013-11-04 20:10:10 -08009773 pHddStaCtx->conn_info.ucEncryptionType)
Jeff Johnson295189b2012-06-20 16:38:30 -07009774 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309775 {
9776 /* if default key index is not same as previous one,
Jeff Johnson295189b2012-06-20 16:38:30 -07009777 * then update the default key index */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309778
Jeff Johnson295189b2012-06-20 16:38:30 -07009779 tCsrRoamSetKey setKey;
9780 v_U32_t roamId= 0xFF;
9781 tCsrKeys *Keys = &pWextState->roamProfile.Keys;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309782
9783 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: default tx key index %d",
Jeff Johnson295189b2012-06-20 16:38:30 -07009784 __func__, key_index);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309785
Jeff Johnson295189b2012-06-20 16:38:30 -07009786 Keys->defaultIndex = (u8)key_index;
9787 vos_mem_zero(&setKey,sizeof(tCsrRoamSetKey));
9788 setKey.keyId = key_index;
9789 setKey.keyLength = Keys->KeyLength[key_index];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309790
9791 vos_mem_copy(&setKey.Key[0],
9792 &Keys->KeyMaterial[key_index][0],
Jeff Johnson295189b2012-06-20 16:38:30 -07009793 Keys->KeyLength[key_index]);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309794
Gopichand Nakkala29149562013-05-10 21:43:41 +05309795 setKey.keyDirection = eSIR_TX_RX;
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309796
9797 vos_mem_copy(setKey.peerMac,
Jeff Johnson295189b2012-06-20 16:38:30 -07009798 &pHddStaCtx->conn_info.bssId[0],
9799 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309800
Gopichand Nakkala29149562013-05-10 21:43:41 +05309801 if (Keys->KeyLength[key_index] == CSR_WEP40_KEY_LEN &&
9802 pWextState->roamProfile.EncryptionType.encryptionType[0] ==
9803 eCSR_ENCRYPT_TYPE_WEP104)
9804 {
9805 /*In the case of dynamic wep supplicant hardcodes DWEP type to eCSR_ENCRYPT_TYPE_WEP104
9806 even though ap is configured for WEP-40 encryption. In this canse the key length
9807 is 5 but the encryption type is 104 hence checking the key langht(5) and encryption
9808 type(104) and switching encryption type to 40*/
9809 pWextState->roamProfile.EncryptionType.encryptionType[0] =
9810 eCSR_ENCRYPT_TYPE_WEP40;
9811 pWextState->roamProfile.mcEncryptionType.encryptionType[0] =
9812 eCSR_ENCRYPT_TYPE_WEP40;
9813 }
9814
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309815 setKey.encType =
Jeff Johnson295189b2012-06-20 16:38:30 -07009816 pWextState->roamProfile.EncryptionType.encryptionType[0];
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309817
Jeff Johnson295189b2012-06-20 16:38:30 -07009818 /* issue set key request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309819 status = sme_RoamSetKey( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -07009820 pAdapter->sessionId, &setKey, &roamId );
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309821
Jeff Johnson295189b2012-06-20 16:38:30 -07009822 if ( 0 != status )
9823 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309824 hddLog(VOS_TRACE_LEVEL_ERROR,
9825 "%s: sme_RoamSetKey failed, returned %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -07009826 status);
9827 return -EINVAL;
9828 }
9829 }
9830 }
9831
9832 /* In SoftAp mode setting key direction for default mode */
9833 else if ( WLAN_HDD_SOFTAP == pAdapter->device_mode )
9834 {
9835 if ( (eCSR_ENCRYPT_TYPE_TKIP !=
9836 pWextState->roamProfile.EncryptionType.encryptionType[0]) &&
9837 (eCSR_ENCRYPT_TYPE_AES !=
9838 pWextState->roamProfile.EncryptionType.encryptionType[0])
9839 )
9840 {
9841 /* Saving key direction for default key index to TX default */
9842 hdd_ap_ctx_t *pAPCtx = WLAN_HDD_GET_AP_CTX_PTR(pAdapter);
9843 pAPCtx->wepKey[key_index].keyDirection = eSIR_TX_DEFAULT;
9844 }
9845 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309846 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -07009847 return status;
9848}
9849
Mahesh A Saptasagar1a51bc02014-06-02 18:28:08 +05309850#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9851static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9852 struct net_device *ndev,
9853 u8 key_index,
9854 bool unicast, bool multicast)
9855#else
9856static int wlan_hdd_cfg80211_set_default_key( struct wiphy *wiphy,
9857 struct net_device *ndev,
9858 u8 key_index)
9859#endif
9860{
9861 int ret;
9862 vos_ssr_protect(__func__);
9863#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
9864 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index, unicast,
9865 multicast);
9866#else
9867 ret = __wlan_hdd_cfg80211_set_default_key(wiphy, ndev, key_index);
9868#endif
9869 vos_ssr_unprotect(__func__);
9870
9871 return ret;
9872}
9873
Jeff Johnson295189b2012-06-20 16:38:30 -07009874/*
9875 * FUNCTION: wlan_hdd_cfg80211_inform_bss
9876 * This function is used to inform the BSS details to nl80211 interface.
9877 */
9878static struct cfg80211_bss* wlan_hdd_cfg80211_inform_bss(
9879 hdd_adapter_t *pAdapter, tCsrRoamConnectedProfile *roamProfile)
9880{
9881 struct net_device *dev = pAdapter->dev;
9882 struct wireless_dev *wdev = dev->ieee80211_ptr;
9883 struct wiphy *wiphy = wdev->wiphy;
9884 tSirBssDescription *pBssDesc = roamProfile->pBssDesc;
9885 int chan_no;
9886 int ie_length;
9887 const char *ie;
9888 unsigned int freq;
9889 struct ieee80211_channel *chan;
9890 int rssi = 0;
9891 struct cfg80211_bss *bss = NULL;
9892
Jeff Johnson295189b2012-06-20 16:38:30 -07009893 if( NULL == pBssDesc )
9894 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009895 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pBssDesc is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009896 return bss;
9897 }
9898
9899 chan_no = pBssDesc->channelId;
9900 ie_length = GET_IE_LEN_IN_BSS_DESC( pBssDesc->length );
9901 ie = ((ie_length != 0) ? (const char *)&pBssDesc->ieFields: NULL);
9902
9903 if( NULL == ie )
9904 {
Arif Hussain6d2a3322013-11-17 19:50:10 -08009905 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: IE of BSS descriptor is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07009906 return bss;
9907 }
9908
9909#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
9910 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ))
9911 {
9912 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
9913 }
9914 else
9915 {
9916 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
9917 }
9918#else
9919 freq = ieee80211_channel_to_frequency(chan_no);
9920#endif
9921
9922 chan = __ieee80211_get_channel(wiphy, freq);
9923
Santhosh Kumar Padmaa45fdb12014-04-15 15:54:38 +05309924 if (!chan) {
9925 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
9926 return NULL;
9927 }
9928
Abhishek Singhaee43942014-06-16 18:55:47 +05309929 rssi = (VOS_MIN ((pBssDesc->rssi + pBssDesc->sinr), 0))*100;
Jeff Johnson295189b2012-06-20 16:38:30 -07009930
Anand N Sunkad9f80b742015-07-30 20:05:51 +05309931 return cfg80211_inform_bss(wiphy, chan,
9932#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
9933 CFG80211_BSS_FTYPE_UNKNOWN,
9934#endif
9935 pBssDesc->bssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +05309936 le64_to_cpu(*(__le64 *)pBssDesc->timeStamp),
Jeff Johnson295189b2012-06-20 16:38:30 -07009937 pBssDesc->capabilityInfo,
9938 pBssDesc->beaconInterval, ie, ie_length,
Abhishek Singhaee43942014-06-16 18:55:47 +05309939 rssi, GFP_KERNEL );
Jeff Johnson295189b2012-06-20 16:38:30 -07009940}
9941
9942
9943
9944/*
9945 * FUNCTION: wlan_hdd_cfg80211_inform_bss_frame
9946 * This function is used to inform the BSS details to nl80211 interface.
9947 */
9948struct cfg80211_bss*
9949wlan_hdd_cfg80211_inform_bss_frame( hdd_adapter_t *pAdapter,
9950 tSirBssDescription *bss_desc
9951 )
9952{
9953 /*
9954 cfg80211_inform_bss() is not updating ie field of bss entry, if entry
9955 already exists in bss data base of cfg80211 for that particular BSS ID.
9956 Using cfg80211_inform_bss_frame to update the bss entry instead of
9957 cfg80211_inform_bss, But this call expects mgmt packet as input. As of
9958 now there is no possibility to get the mgmt(probe response) frame from PE,
9959 converting bss_desc to ieee80211_mgmt(probe response) and passing to
9960 cfg80211_inform_bss_frame.
9961 */
9962 struct net_device *dev = pAdapter->dev;
9963 struct wireless_dev *wdev = dev->ieee80211_ptr;
9964 struct wiphy *wiphy = wdev->wiphy;
9965 int chan_no = bss_desc->channelId;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009966#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
9967 qcom_ie_age *qie_age = NULL;
9968 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length ) + sizeof(qcom_ie_age);
9969#else
Jeff Johnson295189b2012-06-20 16:38:30 -07009970 int ie_length = GET_IE_LEN_IN_BSS_DESC( bss_desc->length );
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -08009971#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009972 const char *ie =
9973 ((ie_length != 0) ? (const char *)&bss_desc->ieFields: NULL);
9974 unsigned int freq;
9975 struct ieee80211_channel *chan;
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309976 struct ieee80211_mgmt *mgmt = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -07009977 struct cfg80211_bss *bss_status = NULL;
9978 size_t frame_len = sizeof (struct ieee80211_mgmt) + ie_length;
9979 int rssi = 0;
Wilson Yangf80a0542013-10-07 13:02:37 -07009980 hdd_context_t *pHddCtx;
9981 int status;
Jeff Johnsone7245742012-09-05 17:12:55 -07009982#ifdef WLAN_OPEN_SOURCE
9983 struct timespec ts;
9984#endif
Jeff Johnson295189b2012-06-20 16:38:30 -07009985
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +05309986
Wilson Yangf80a0542013-10-07 13:02:37 -07009987 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
9988 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yangf80a0542013-10-07 13:02:37 -07009989 if (0 != status)
9990 {
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -07009991 return NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -07009992 }
9993
Abhishek Singh1e2bfa32014-01-02 15:44:15 +05309994 mgmt = kzalloc((sizeof (struct ieee80211_mgmt) + ie_length), GFP_KERNEL);
Wilson Yangf80a0542013-10-07 13:02:37 -07009995 if (!mgmt)
9996 {
9997 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
9998 "%s: memory allocation failed ", __func__);
9999 return NULL;
10000 }
Madan Mohan Koyyalamudi2e5c9142012-11-02 13:17:48 -070010001
Jeff Johnson295189b2012-06-20 16:38:30 -070010002 memcpy(mgmt->bssid, bss_desc->bssId, ETH_ALEN);
Jeff Johnsone7245742012-09-05 17:12:55 -070010003
10004#ifdef WLAN_OPEN_SOURCE
10005 /* Android does not want the timestamp from the frame.
10006 Instead it wants a monotonic increasing value */
10007 get_monotonic_boottime(&ts);
10008 mgmt->u.probe_resp.timestamp =
10009 ((u64)ts.tv_sec * 1000000) + (ts.tv_nsec / 1000);
10010#else
10011 /* keep old behavior for non-open source (for now) */
Jeff Johnson295189b2012-06-20 16:38:30 -070010012 memcpy(&mgmt->u.probe_resp.timestamp, bss_desc->timeStamp,
10013 sizeof (bss_desc->timeStamp));
Jeff Johnsone7245742012-09-05 17:12:55 -070010014
10015#endif
10016
Jeff Johnson295189b2012-06-20 16:38:30 -070010017 mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
10018 mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
Madan Mohan Koyyalamudi86f629e2012-11-09 16:27:29 -080010019
10020#ifdef WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS
10021 /* GPS Requirement: need age ie per entry. Using vendor specific. */
10022 /* Assuming this is the last IE, copy at the end */
10023 ie_length -=sizeof(qcom_ie_age);
10024 qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + ie_length);
10025 qie_age->element_id = QCOM_VENDOR_IE_ID;
10026 qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
10027 qie_age->oui_1 = QCOM_OUI1;
10028 qie_age->oui_2 = QCOM_OUI2;
10029 qie_age->oui_3 = QCOM_OUI3;
10030 qie_age->type = QCOM_VENDOR_IE_AGE_TYPE;
10031 qie_age->age = vos_timer_get_system_ticks() - bss_desc->nReceivedTime;
10032#endif
10033
Jeff Johnson295189b2012-06-20 16:38:30 -070010034 memcpy(mgmt->u.probe_resp.variable, ie, ie_length);
Gopichand Nakkalad908ec82013-05-16 19:32:19 +053010035 if (bss_desc->fProbeRsp)
10036 {
10037 mgmt->frame_control |=
10038 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP);
10039 }
10040 else
10041 {
10042 mgmt->frame_control |=
10043 (u16)(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
10044 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010045
10046#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,38))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010047 if (chan_no <= ARRAY_SIZE(hdd_channels_2_4_GHZ) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010048 (wiphy->bands[IEEE80211_BAND_2GHZ] != NULL))
10049 {
10050 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_2GHZ);
10051 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010052 else if ((chan_no > ARRAY_SIZE(hdd_channels_2_4_GHZ)) &&
Jeff Johnson295189b2012-06-20 16:38:30 -070010053 (wiphy->bands[IEEE80211_BAND_5GHZ] != NULL))
10054
10055 {
10056 freq = ieee80211_channel_to_frequency(chan_no, IEEE80211_BAND_5GHZ);
10057 }
10058 else
10059 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010060 hddLog(VOS_TRACE_LEVEL_ERROR, "%s Invalid chan_no:%d",
10061 __func__, chan_no);
Jeff Johnson295189b2012-06-20 16:38:30 -070010062 kfree(mgmt);
10063 return NULL;
10064 }
10065#else
10066 freq = ieee80211_channel_to_frequency(chan_no);
10067#endif
10068 chan = __ieee80211_get_channel(wiphy, freq);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010069 /*when the band is changed on the fly using the GUI, three things are done
10070 * 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)
10071 * as part of the scan abort, message willbe queued to PE and we proceed with flushing and changinh the band.
10072 * pe will stop the scanning further and report back the results what ever it had till now by calling the call back function.
10073 * if the time between update band and scandone call back is sufficent enough the band change reflects in SME, SME validates the channels
10074 * and discards the channels correponding to previous band and calls back with zero bss results.
10075 * 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
10076 * all the channels correponding to previous band.this is due to race condition.but those channels are invalid to the new band and so
10077 * this function __ieee80211_get_channel will return NULL.Each time we report scan result with this pointer null warning kernel trace is printed.
10078 * if the scan results contain large number of APs continuosly kernel warning trace is printed and it will lead to apps watch dog bark.
10079 * So drop the bss and continue to next bss.
10080 */
10081 if(chan == NULL)
10082 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010083 hddLog(VOS_TRACE_LEVEL_ERROR, "%s chan pointer is NULL", __func__);
Chilam Ngc4244af2013-04-01 15:37:32 -070010084 kfree(mgmt);
Leela V Kiran Kumar Reddy90032de2013-01-24 18:33:30 -080010085 return NULL;
10086 }
Hanumantha Reddy Pothula904bcef2015-06-19 11:56:29 +053010087 /*To keep the rssi icon of the connected AP in the scan window
10088 *and the rssi icon of the wireless networks in sync
10089 * */
10090 if (( eConnectionState_Associated ==
10091 pAdapter->sessionCtx.station.conn_info.connState ) &&
10092 ( VOS_TRUE == vos_mem_compare(bss_desc->bssId,
10093 pAdapter->sessionCtx.station.conn_info.bssId,
10094 WNI_CFG_BSSID_LEN)) &&
10095 (pHddCtx->hdd_wlan_suspended == FALSE))
10096 {
10097 /* supplicant takes the signal strength in terms of mBm(100*dBm) */
10098 rssi = (pAdapter->rssi * 100);
10099 }
10100 else
10101 {
10102 rssi = (VOS_MIN ((bss_desc->rssi + bss_desc->sinr), 0))*100;
10103 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010104
Nirav Shah20ac06f2013-12-12 18:14:06 +053010105 hddLog(VOS_TRACE_LEVEL_INFO, "%s: BSSID:" MAC_ADDRESS_STR " Channel:%d"
Sushant Kaushik0b343422015-05-25 17:15:55 +053010106 " RSSI:%d", __func__, MAC_ADDR_ARRAY(mgmt->bssid),
10107 vos_freq_to_chan(chan->center_freq), (int)(rssi/100));
Nirav Shah20ac06f2013-12-12 18:14:06 +053010108
Jeff Johnson295189b2012-06-20 16:38:30 -070010109 bss_status = cfg80211_inform_bss_frame(wiphy, chan, mgmt,
10110 frame_len, rssi, GFP_KERNEL);
10111 kfree(mgmt);
10112 return bss_status;
10113}
10114
10115/*
10116 * FUNCTION: wlan_hdd_cfg80211_update_bss_db
10117 * This function is used to update the BSS data base of CFG8011
10118 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010119struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070010120 tCsrRoamInfo *pRoamInfo
10121 )
10122{
10123 tCsrRoamConnectedProfile roamProfile;
10124 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
10125 struct cfg80211_bss *bss = NULL;
10126
10127 ENTER();
10128
10129 memset(&roamProfile, 0, sizeof(tCsrRoamConnectedProfile));
10130 sme_RoamGetConnectProfile(hHal, pAdapter->sessionId, &roamProfile);
10131
10132 if (NULL != roamProfile.pBssDesc)
10133 {
Girish Gowlif4b68022014-08-28 23:18:57 +053010134 bss = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10135 roamProfile.pBssDesc);
Jeff Johnson295189b2012-06-20 16:38:30 -070010136
10137 if (NULL == bss)
10138 {
10139 hddLog(VOS_TRACE_LEVEL_INFO, "%s: cfg80211_inform_bss return NULL",
10140 __func__);
10141 }
10142
10143 sme_RoamFreeConnectProfile(hHal, &roamProfile);
10144 }
10145 else
10146 {
10147 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: roamProfile.pBssDesc is NULL",
10148 __func__);
10149 }
10150 return bss;
10151}
10152
10153/*
10154 * FUNCTION: wlan_hdd_cfg80211_update_bss
10155 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010156static int wlan_hdd_cfg80211_update_bss( struct wiphy *wiphy,
10157 hdd_adapter_t *pAdapter
Jeff Johnson295189b2012-06-20 16:38:30 -070010158 )
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010159{
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010160 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070010161 tCsrScanResultInfo *pScanResult;
10162 eHalStatus status = 0;
10163 tScanResultHandle pResult;
10164 struct cfg80211_bss *bss_status = NULL;
Wilson Yangf80a0542013-10-07 13:02:37 -070010165 hdd_context_t *pHddCtx;
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010166 bool is_p2p_scan = false;
Jeff Johnson295189b2012-06-20 16:38:30 -070010167 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010168
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053010169 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10170 TRACE_CODE_HDD_CFG80211_UPDATE_BSS,
10171 NO_SESSION, pAdapter->sessionId));
10172
Wilson Yangf80a0542013-10-07 13:02:37 -070010173 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
10174
10175 if (pHddCtx->isLogpInProgress)
Jeff Johnson295189b2012-06-20 16:38:30 -070010176 {
Wilson Yangf80a0542013-10-07 13:02:37 -070010177 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
10178 "%s:LOGP in Progress. Ignore!!!",__func__);
10179 return -EAGAIN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010180 }
10181
Wilson Yangf80a0542013-10-07 13:02:37 -070010182
10183 /*bss_update is not allowed during wlan driver loading or unloading*/
Mihir Shete18156292014-03-11 15:38:30 +053010184 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Wilson Yangf80a0542013-10-07 13:02:37 -070010185 {
10186 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10187 "%s:Loading_unloading in Progress. Ignore!!!",__func__);
10188 return VOS_STATUS_E_PERM;
10189 }
10190
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010191 if (pAdapter->request != NULL)
10192 {
10193 if ((pAdapter->request->n_ssids == 1)
10194 && (pAdapter->request->ssids != NULL)
10195 && vos_mem_compare(&pAdapter->request->ssids[0], "DIRECT-", 7))
10196 is_p2p_scan = true;
10197 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010198 /*
10199 * start getting scan results and populate cgf80211 BSS database
10200 */
10201 status = sme_ScanGetResult(hHal, pAdapter->sessionId, NULL, &pResult);
10202
10203 /* no scan results */
10204 if (NULL == pResult)
10205 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010206 hddLog(VOS_TRACE_LEVEL_INFO, "%s: No scan result Status %d",
10207 __func__, status);
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053010208 wlan_hdd_get_frame_logs(pAdapter,
10209 WLAN_HDD_GET_FRAME_LOG_CMD_SEND_AND_CLEAR);
Jeff Johnson295189b2012-06-20 16:38:30 -070010210 return status;
10211 }
10212
10213 pScanResult = sme_ScanResultGetFirst(hHal, pResult);
10214
10215 while (pScanResult)
10216 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010217 /*
10218 * cfg80211_inform_bss() is not updating ie field of bss entry, if
10219 * entry already exists in bss data base of cfg80211 for that
10220 * particular BSS ID. Using cfg80211_inform_bss_frame to update the
10221 * bss entry instead of cfg80211_inform_bss, But this call expects
10222 * mgmt packet as input. As of now there is no possibility to get
10223 * the mgmt(probe response) frame from PE, converting bss_desc to
Jeff Johnson295189b2012-06-20 16:38:30 -070010224 * ieee80211_mgmt(probe response) and passing to c
10225 * fg80211_inform_bss_frame.
10226 * */
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010227 if(is_p2p_scan && (pScanResult->ssId.ssId != NULL) &&
10228 !vos_mem_compare( pScanResult->ssId.ssId, "DIRECT-", 7) )
10229 {
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010230 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10231 continue; //Skip the non p2p bss entries
10232 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010233 bss_status = wlan_hdd_cfg80211_inform_bss_frame(pAdapter,
10234 &pScanResult->BssDescriptor);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010235
Jeff Johnson295189b2012-06-20 16:38:30 -070010236
10237 if (NULL == bss_status)
10238 {
10239 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010240 "%s: NULL returned by cfg80211_inform_bss", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010241 }
10242 else
10243 {
Yue Maf49ba872013-08-19 12:04:25 -070010244 cfg80211_put_bss(
10245#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
10246 wiphy,
10247#endif
10248 bss_status);
Jeff Johnson295189b2012-06-20 16:38:30 -070010249 }
10250
10251 pScanResult = sme_ScanResultGetNext(hHal, pResult);
10252 }
10253
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010254 sme_ScanResultPurge(hHal, pResult);
Deepthi Gowri10d0ae12015-05-25 14:39:50 +053010255 is_p2p_scan = false;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010256 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010257}
10258
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010259void
10260hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel)
10261{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010262 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussaina7c8e412013-11-20 11:06:42 -080010263 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(macAddr));
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010264} /****** end hddPrintMacAddr() ******/
10265
10266void
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010267hddPrintPmkId(tANI_U8 *pmkId, tANI_U8 logLevel)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010268{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010269 VOS_TRACE(VOS_MODULE_ID_HDD, logLevel,
Arif Hussain6d2a3322013-11-17 19:50:10 -080010270 "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070010271 pmkId[0], pmkId[1], pmkId[2], pmkId[3], pmkId[4],
10272 pmkId[5], pmkId[6], pmkId[7], pmkId[8], pmkId[9], pmkId[10],
10273 pmkId[11], pmkId[12], pmkId[13], pmkId[14], pmkId[15]);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010274} /****** end hddPrintPmkId() ******/
10275
10276//hddPrintMacAddr(tCsrBssid macAddr, tANI_U8 logLevel);
10277//hddPrintMacAddr(macAddr, VOS_TRACE_LEVEL_FATAL);
10278
10279//void sirDumpBuf(tpAniSirGlobal pMac, tANI_U8 modId, tANI_U32 level, tANI_U8 *buf, tANI_U32 size);
10280//sirDumpBuf(pMac, VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL, pmkid, 16);
10281
10282#define dump_bssid(bssid) \
10283 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010284 hddLog(VOS_TRACE_LEVEL_INFO, "BSSID (MAC) address:\t"); \
10285 hddPrintMacAddr(bssid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010286 }
10287
10288#define dump_pmkid(pMac, pmkid) \
10289 { \
Jeff Johnsone7245742012-09-05 17:12:55 -070010290 hddLog(VOS_TRACE_LEVEL_INFO, "PMKSA-ID:\t"); \
10291 hddPrintPmkId(pmkid, VOS_TRACE_LEVEL_INFO);\
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010292 }
10293
Madan Mohan Koyyalamudi1b4afb02012-10-22 15:25:16 -070010294#if defined(FEATURE_WLAN_LFR) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010295/*
10296 * FUNCTION: wlan_hdd_cfg80211_pmksa_candidate_notify
10297 * This function is used to notify the supplicant of a new PMKSA candidate.
10298 */
10299int wlan_hdd_cfg80211_pmksa_candidate_notify(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010300 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010301 int index, bool preauth )
10302{
Jeff Johnsone7245742012-09-05 17:12:55 -070010303#ifdef FEATURE_WLAN_OKC
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010304 struct net_device *dev = pAdapter->dev;
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010305 hdd_context_t *pHddCtx = (hdd_context_t*)pAdapter->pHddCtx;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010306
10307 ENTER();
Jeff Johnsone7245742012-09-05 17:12:55 -070010308 hddLog(VOS_TRACE_LEVEL_INFO, "%s is going to notify supplicant of:", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010309
10310 if( NULL == pRoamInfo )
10311 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010312 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: pRoamInfo is NULL", __func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010313 return -EINVAL;
10314 }
10315
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010316 if (eANI_BOOLEAN_TRUE == hdd_is_okc_mode_enabled(pHddCtx))
10317 {
10318 dump_bssid(pRoamInfo->bssid);
10319 cfg80211_pmksa_candidate_notify(dev, index,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010320 pRoamInfo->bssid, preauth, GFP_KERNEL);
Srinivas Girigowdabbd16eb2013-03-21 12:34:46 -070010321 }
Jeff Johnsone7245742012-09-05 17:12:55 -070010322#endif /* FEATURE_WLAN_OKC */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010323 return 0;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070010324}
10325#endif //FEATURE_WLAN_LFR
10326
Yue Maef608272013-04-08 23:09:17 -070010327#ifdef FEATURE_WLAN_LFR_METRICS
10328/*
10329 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth
10330 * 802.11r/LFR metrics reporting function to report preauth initiation
10331 *
10332 */
10333#define MAX_LFR_METRICS_EVENT_LENGTH 100
10334VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth(hdd_adapter_t *pAdapter,
10335 tCsrRoamInfo *pRoamInfo)
10336{
10337 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10338 union iwreq_data wrqu;
10339
10340 ENTER();
10341
10342 if (NULL == pAdapter)
10343 {
10344 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10345 return VOS_STATUS_E_FAILURE;
10346 }
10347
10348 /* create the event */
10349 memset(&wrqu, 0, sizeof(wrqu));
10350 memset(metrics_notification, 0, sizeof(metrics_notification));
10351
10352 wrqu.data.pointer = metrics_notification;
10353 wrqu.data.length = scnprintf(metrics_notification,
10354 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_INIT "
10355 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10356
10357 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10358
10359 EXIT();
10360
10361 return VOS_STATUS_SUCCESS;
10362}
10363
10364/*
10365 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_preauth_status
10366 * 802.11r/LFR metrics reporting function to report preauth completion
10367 * or failure
10368 */
10369VOS_STATUS wlan_hdd_cfg80211_roam_metrics_preauth_status(
10370 hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, bool preauth_status)
10371{
10372 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10373 union iwreq_data wrqu;
10374
10375 ENTER();
10376
10377 if (NULL == pAdapter)
10378 {
10379 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10380 return VOS_STATUS_E_FAILURE;
10381 }
10382
10383 /* create the event */
10384 memset(&wrqu, 0, sizeof(wrqu));
10385 memset(metrics_notification, 0, sizeof(metrics_notification));
10386
10387 scnprintf(metrics_notification, sizeof(metrics_notification),
10388 "QCOM: LFR_PREAUTH_STATUS "MAC_ADDRESS_STR,
10389 MAC_ADDR_ARRAY(pRoamInfo->bssid));
10390
10391 if (1 == preauth_status)
10392 strncat(metrics_notification, " TRUE", 5);
10393 else
10394 strncat(metrics_notification, " FALSE", 6);
10395
10396 wrqu.data.pointer = metrics_notification;
10397 wrqu.data.length = strlen(metrics_notification);
10398
10399 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10400
10401 EXIT();
10402
10403 return VOS_STATUS_SUCCESS;
10404}
10405
10406/*
10407 * FUNCTION: wlan_hdd_cfg80211_roam_metrics_handover
10408 * 802.11r/LFR metrics reporting function to report handover initiation
10409 *
10410 */
10411VOS_STATUS wlan_hdd_cfg80211_roam_metrics_handover(hdd_adapter_t * pAdapter,
10412 tCsrRoamInfo *pRoamInfo)
10413{
10414 unsigned char metrics_notification[MAX_LFR_METRICS_EVENT_LENGTH + 1];
10415 union iwreq_data wrqu;
10416
10417 ENTER();
10418
10419 if (NULL == pAdapter)
10420 {
10421 hddLog(LOGE, "%s: pAdapter is NULL!", __func__);
10422 return VOS_STATUS_E_FAILURE;
10423 }
10424
10425 /* create the event */
10426 memset(&wrqu, 0, sizeof(wrqu));
10427 memset(metrics_notification, 0, sizeof(metrics_notification));
10428
10429 wrqu.data.pointer = metrics_notification;
10430 wrqu.data.length = scnprintf(metrics_notification,
10431 sizeof(metrics_notification), "QCOM: LFR_PREAUTH_HANDOVER "
10432 MAC_ADDRESS_STR, MAC_ADDR_ARRAY(pRoamInfo->bssid));
10433
10434 wireless_send_event(pAdapter->dev, IWEVCUSTOM, &wrqu, metrics_notification);
10435
10436 EXIT();
10437
10438 return VOS_STATUS_SUCCESS;
10439}
10440#endif
10441
Jeff Johnson295189b2012-06-20 16:38:30 -070010442/*
10443 * FUNCTION: hdd_cfg80211_scan_done_callback
10444 * scanning callback function, called after finishing scan
10445 *
10446 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010447static eHalStatus hdd_cfg80211_scan_done_callback(tHalHandle halHandle,
Jeff Johnson295189b2012-06-20 16:38:30 -070010448 void *pContext, tANI_U32 scanId, eCsrScanStatus status)
10449{
10450 struct net_device *dev = (struct net_device *) pContext;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010451 //struct wireless_dev *wdev = dev->ieee80211_ptr;
Jeff Johnson295189b2012-06-20 16:38:30 -070010452 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010453 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070010454 struct cfg80211_scan_request *req = NULL;
10455 int ret = 0;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010456 bool aborted = false;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010457 long waitRet = 0;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010458 tANI_U8 i;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010459 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070010460
10461 ENTER();
10462
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010463 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Siddharth Bhal5c2e02d2015-05-05 17:35:29 +053010464 if (NULL == pHddCtx) {
10465 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is Null"));
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053010466 goto allow_suspend;
10467 }
10468
10469 pScanInfo = &pHddCtx->scan_info;
10470
Jeff Johnson295189b2012-06-20 16:38:30 -070010471 hddLog(VOS_TRACE_LEVEL_INFO,
10472 "%s called with halHandle = %p, pContext = %p,"
Arif Hussain6d2a3322013-11-17 19:50:10 -080010473 "scanID = %d, returned status = %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070010474 __func__, halHandle, pContext, (int) scanId, (int) status);
10475
Kiet Lamac06e2c2013-10-23 16:25:07 +053010476 pScanInfo->mScanPendingCounter = 0;
10477
Jeff Johnson295189b2012-06-20 16:38:30 -070010478 //Block on scan req completion variable. Can't wait forever though.
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010479 waitRet = wait_for_completion_interruptible_timeout(
Jeff Johnson295189b2012-06-20 16:38:30 -070010480 &pScanInfo->scan_req_completion_event,
10481 msecs_to_jiffies(WLAN_WAIT_TIME_SCAN_REQ));
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010482 if (waitRet <= 0)
Jeff Johnson295189b2012-06-20 16:38:30 -070010483 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053010484 hddLog(VOS_TRACE_LEVEL_ERROR,
10485 "%s wait on scan_req_completion_event failed %ld",__func__, waitRet);
Jeff Johnson295189b2012-06-20 16:38:30 -070010486 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010487 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010488 }
10489
Yue Maef608272013-04-08 23:09:17 -070010490 if (pScanInfo->mScanPending != VOS_TRUE)
Jeff Johnson295189b2012-06-20 16:38:30 -070010491 {
10492 VOS_ASSERT(pScanInfo->mScanPending);
Jeff Johnsone7245742012-09-05 17:12:55 -070010493 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010494 }
10495
10496 /* Check the scanId */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010497 if (pScanInfo->scanId != scanId)
Jeff Johnson295189b2012-06-20 16:38:30 -070010498 {
10499 hddLog(VOS_TRACE_LEVEL_INFO,
10500 "%s called with mismatched scanId pScanInfo->scanId = %d "
Arif Hussain6d2a3322013-11-17 19:50:10 -080010501 "scanId = %d", __func__, (int) pScanInfo->scanId,
Jeff Johnson295189b2012-06-20 16:38:30 -070010502 (int) scanId);
10503 }
10504
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010505 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070010506 pAdapter);
10507
10508 if (0 > ret)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010509 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010510
10511
10512 /* If any client wait scan result through WEXT
10513 * send scan done event to client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010514 if (pHddCtx->scan_info.waitScanResult)
Jeff Johnson295189b2012-06-20 16:38:30 -070010515 {
10516 /* The other scan request waiting for current scan finish
10517 * Send event to notify current scan finished */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010518 if(WEXT_SCAN_PENDING_DELAY == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010519 {
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010520 vos_event_set(&pHddCtx->scan_info.scan_finished_event);
Jeff Johnson295189b2012-06-20 16:38:30 -070010521 }
10522 /* Send notify to WEXT client */
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010523 else if(WEXT_SCAN_PENDING_PIGGYBACK == pHddCtx->scan_info.scan_pending_option)
Jeff Johnson295189b2012-06-20 16:38:30 -070010524 {
10525 struct net_device *dev = pAdapter->dev;
10526 union iwreq_data wrqu;
10527 int we_event;
10528 char *msg;
10529
10530 memset(&wrqu, '\0', sizeof(wrqu));
10531 we_event = SIOCGIWSCAN;
10532 msg = NULL;
10533 wireless_send_event(dev, we_event, &wrqu, msg);
10534 }
10535 }
Madan Mohan Koyyalamudi2a1ba772012-10-11 14:59:06 -070010536 pHddCtx->scan_info.waitScanResult = FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010537
10538 /* Get the Scan Req */
10539 req = pAdapter->request;
10540
10541 if (!req)
10542 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080010543 hddLog(VOS_TRACE_LEVEL_ERROR, "request is became NULL");
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010544 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnsone7245742012-09-05 17:12:55 -070010545 goto allow_suspend;
Jeff Johnson295189b2012-06-20 16:38:30 -070010546 }
10547
Jeff Johnson295189b2012-06-20 16:38:30 -070010548 pAdapter->request = NULL;
Jeff Johnsone7245742012-09-05 17:12:55 -070010549 /* Scan is no longer pending */
10550 pScanInfo->mScanPending = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070010551
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010552 /* last_scan_timestamp is used to decide if new scan
10553 * is needed or not on station interface. If last station
10554 * scan time and new station scan time is less then
10555 * last_scan_timestamp ; driver will return cached scan.
10556 */
10557 if (req->no_cck == FALSE && status == eCSR_SCAN_SUCCESS) // no_cck will be set during p2p find
10558 {
10559 pScanInfo->last_scan_timestamp = vos_timer_get_system_time();
10560
10561 if ( req->n_channels )
10562 {
10563 for (i = 0; i < req->n_channels ; i++ )
10564 {
10565 pHddCtx->scan_info.last_scan_channelList[i] = req->channels[i]->hw_value;
10566 }
10567 /* store no of channel scanned */
10568 pHddCtx->scan_info.last_scan_numChannels= req->n_channels;
10569 }
10570
10571 }
10572
Madan Mohan Koyyalamudib764bf82012-10-11 16:38:51 -070010573 /*
10574 * cfg80211_scan_done informing NL80211 about completion
10575 * of scanning
10576 */
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053010577 if (status == eCSR_SCAN_ABORT || status == eCSR_SCAN_FAILURE)
10578 {
10579 aborted = true;
10580 }
10581 cfg80211_scan_done(req, aborted);
Madan Mohan Koyyalamudif4e81002012-11-13 10:46:38 -080010582 complete(&pScanInfo->abortscan_event_var);
Jeff Johnson295189b2012-06-20 16:38:30 -070010583
Siddharth Bhal76972212014-10-15 16:22:51 +053010584 if (pHddCtx->spoofMacAddr.isEnabled || pHddCtx->spoofMacAddr.isReqDeferred) {
10585 /* Generate new random mac addr for next scan */
10586 hddLog(VOS_TRACE_LEVEL_INFO, "scan completed - generate new spoof mac addr");
10587 hdd_processSpoofMacAddrRequest(pHddCtx);
10588 }
10589
Jeff Johnsone7245742012-09-05 17:12:55 -070010590allow_suspend:
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070010591 /* release the wake lock at the end of the scan*/
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010592 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070010593
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010594 /* Acquire wakelock to handle the case where APP's tries to suspend
10595 * immediatly after the driver gets connect request(i.e after scan)
10596 * from supplicant, this result in app's is suspending and not able
10597 * to process the connect request to AP */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053010598 hdd_prevent_suspend_timeout(1000, WIFI_POWER_EVENT_WAKELOCK_SCAN);
Madan Mohan Koyyalamudi10d83a92012-09-28 15:47:05 -070010599
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010600#ifdef FEATURE_WLAN_TDLS
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053010601 wlan_hdd_tdls_scan_done_callback(pAdapter);
Gopichand Nakkala638ebc72013-03-21 18:04:02 -070010602#endif
10603
Jeff Johnson295189b2012-06-20 16:38:30 -070010604 EXIT();
10605 return 0;
10606}
10607
10608/*
Rashmi Ramannab1429032014-04-26 14:59:09 +053010609 * FUNCTION: hdd_isConnectionInProgress
10610 * Go through each adapter and check if Connection is in progress
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010611 *
10612 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010613v_BOOL_t hdd_isConnectionInProgress( hdd_context_t *pHddCtx)
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010614{
10615 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
10616 hdd_station_ctx_t *pHddStaCtx = NULL;
10617 hdd_adapter_t *pAdapter = NULL;
10618 VOS_STATUS status = 0;
10619 v_U8_t staId = 0;
10620 v_U8_t *staMac = NULL;
10621
c_hpothu9b781ba2013-12-30 20:57:45 +053010622 if (TRUE == pHddCtx->btCoexModeSet)
10623 {
10624 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Rashmi Ramannab1429032014-04-26 14:59:09 +053010625 FL("BTCoex Mode operation in progress"));
10626 return VOS_TRUE;
c_hpothu9b781ba2013-12-30 20:57:45 +053010627 }
10628
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010629 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
10630
10631 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
10632 {
10633 pAdapter = pAdapterNode->pAdapter;
10634
10635 if( pAdapter )
10636 {
10637 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010638 "%s: Adapter with device mode %s (%d) exists",
10639 __func__, hdd_device_modetoString(pAdapter->device_mode),
10640 pAdapter->device_mode);
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010641 if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Rashmi Ramannab1429032014-04-26 14:59:09 +053010642 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10643 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode)) &&
10644 (eConnectionState_Connecting ==
10645 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
10646 {
10647 hddLog(VOS_TRACE_LEVEL_ERROR,
10648 "%s: %p(%d) Connection is in progress", __func__,
10649 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10650 return VOS_TRUE;
10651 }
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010652 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Padma, Santhosh Kumar3b9657d2015-02-04 19:37:32 +053010653 smeNeighborMiddleOfRoaming(WLAN_HDD_GET_HAL_CTX(pAdapter)))
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010654 {
10655 hddLog(VOS_TRACE_LEVEL_ERROR,
10656 "%s: %p(%d) Reassociation is in progress", __func__,
10657 WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pAdapter->sessionId);
10658 return VOS_TRUE;
10659 }
10660 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010661 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
10662 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010663 {
10664 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10665 if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) &&
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010666 (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010667 {
10668 staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]);
10669 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010670 "%s: client " MAC_ADDRESS_STR
10671 " is in the middle of WPS/EAPOL exchange.", __func__,
10672 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010673 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010674 }
10675 }
10676 else if ((WLAN_HDD_SOFTAP == pAdapter->device_mode) ||
10677 (WLAN_HDD_P2P_GO == pAdapter->device_mode))
10678 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010679 v_CONTEXT_t pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
10680 ptSapContext pSapCtx = NULL;
10681 pSapCtx = VOS_GET_SAP_CB(pVosContext);
10682 if(pSapCtx == NULL){
10683 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
10684 FL("psapCtx is NULL"));
10685 return VOS_FALSE;
10686 }
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010687 for (staId = 0; staId < WLAN_MAX_STA_COUNT; staId++)
10688 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010689 if ((pSapCtx->aStaInfo[staId].isUsed) &&
10690 (WLANTL_STA_CONNECTED == pSapCtx->aStaInfo[staId].tlSTAState))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010691 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053010692 staMac = (v_U8_t *) &(pSapCtx->aStaInfo[staId].macAddrSTA.bytes[0]);
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010693
10694 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain24bafea2013-11-15 15:10:03 -080010695 "%s: client " MAC_ADDRESS_STR " of SoftAP/P2P-GO is in the "
10696 "middle of WPS/EAPOL exchange.", __func__,
10697 MAC_ADDR_ARRAY(staMac));
Rashmi Ramannab1429032014-04-26 14:59:09 +053010698 return VOS_TRUE;
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010699 }
10700 }
10701 }
10702 }
10703 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
10704 pAdapterNode = pNext;
10705 }
Rashmi Ramannab1429032014-04-26 14:59:09 +053010706 return VOS_FALSE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010707}
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010708
10709/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010710 * FUNCTION: __wlan_hdd_cfg80211_scan
Jeff Johnson295189b2012-06-20 16:38:30 -070010711 * this scan respond to scan trigger and update cfg80211 scan database
10712 * later, scan dump command can be used to recieve scan results
10713 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053010714int __wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080010715#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
10716 struct net_device *dev,
10717#endif
10718 struct cfg80211_scan_request *request)
10719{
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010720 hdd_adapter_t *pAdapter = NULL;
10721 hdd_context_t *pHddCtx = NULL;
10722 hdd_wext_state_t *pwextBuf = NULL;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010723 hdd_config_t *cfg_param = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010724 tCsrScanRequest scanRequest;
10725 tANI_U8 *channelList = NULL, i;
10726 v_U32_t scanId = 0;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010727 int status;
10728 hdd_scaninfo_t *pScanInfo = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010729 v_U8_t* pP2pIe = NULL;
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010730 int ret = 0;
Sushant Kaushik86592172015-04-27 16:35:03 +053010731 v_U8_t *pWpsIe=NULL;
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010732 bool is_p2p_scan = false;
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053010733 v_S7_t rssi=0;
10734 hdd_station_ctx_t *pHddStaCtx=NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070010735
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010736#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,6,0))
10737 struct net_device *dev = NULL;
10738 if (NULL == request)
10739 {
10740 hddLog(VOS_TRACE_LEVEL_ERROR,
10741 "%s: scan req param null", __func__);
10742 return -EINVAL;
10743 }
10744 dev = request->wdev->netdev;
10745#endif
10746
10747 pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
10748 pHddCtx = WLAN_HDD_GET_CTX( pAdapter );
10749 pwextBuf = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
10750
Jeff Johnson295189b2012-06-20 16:38:30 -070010751 ENTER();
10752
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010753 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)",
10754 __func__, hdd_device_modetoString(pAdapter->device_mode),
10755 pAdapter->device_mode);
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053010756
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010757 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010758 if (0 != status)
10759 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010760 return status;
10761 }
10762
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010763 if (NULL == pwextBuf)
10764 {
10765 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: invalid WEXT state\n",
10766 __func__);
10767 return -EIO;
10768 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053010769 cfg_param = pHddCtx->cfg_ini;
10770 pScanInfo = &pHddCtx->scan_info;
10771
Hanumantha Reddy Pothula2e282d12015-06-19 14:01:26 +053010772 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
10773 if ( (pHddStaCtx != NULL) && (TRUE == hdd_connIsConnected(pHddStaCtx)))
10774 {
10775 wlan_hdd_get_roam_rssi(pAdapter, &rssi);
10776 hddLog(VOS_TRACE_LEVEL_INFO, FL("rssi: %d"), rssi);
10777 }
10778
Jeff Johnson295189b2012-06-20 16:38:30 -070010779#ifdef WLAN_BTAMP_FEATURE
10780 //Scan not supported when AMP traffic is on.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010781 if (VOS_TRUE == WLANBAP_AmpSessionOn())
Jeff Johnson295189b2012-06-20 16:38:30 -070010782 {
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080010783 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010784 "%s: No scanning when AMP is on", __func__);
10785 return -EOPNOTSUPP;
10786 }
10787#endif
10788 //Scan on any other interface is not supported.
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010789 if (pAdapter->device_mode == WLAN_HDD_SOFTAP)
Jeff Johnson295189b2012-06-20 16:38:30 -070010790 {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010791 hddLog(VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053010792 "%s: Not scanning on device_mode = %s (%d)",
10793 __func__, hdd_device_modetoString(pAdapter->device_mode),
10794 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070010795 return -EOPNOTSUPP;
10796 }
10797
10798 if (TRUE == pScanInfo->mScanPending)
10799 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010800 if ( MAX_PENDING_LOG > pScanInfo->mScanPendingCounter++ )
10801 {
10802 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: mScanPending is TRUE", __func__);
10803 }
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010804 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010805 }
10806
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010807 //Don't Allow Scan and return busy if Remain On
Jeff Johnson32d95a32012-09-10 13:15:23 -070010808 //Channel and action frame is pending
10809 //Otherwise Cancel Remain On Channel and allow Scan
10810 //If no action frame pending
Gopichand Nakkala681989c2013-03-06 22:27:48 -080010811 if (0 != wlan_hdd_check_remain_on_channel(pAdapter))
Jeff Johnson32d95a32012-09-10 13:15:23 -070010812 {
Kiet Lamac06e2c2013-10-23 16:25:07 +053010813 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Remain On Channel Pending", __func__);
Jeff Johnson32d95a32012-09-10 13:15:23 -070010814 return -EBUSY;
10815 }
10816
Jeff Johnson295189b2012-06-20 16:38:30 -070010817 if (mutex_lock_interruptible(&pHddCtx->tmInfo.tmOperationLock))
10818 {
10819 VOS_TRACE(VOS_MODULE_ID_HDD,VOS_TRACE_LEVEL_ERROR,
Jeff Johnson1250df42012-12-10 14:31:52 -080010820 "%s: Acquire lock fail", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070010821 return -EAGAIN;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010822 }
Jeff Johnson295189b2012-06-20 16:38:30 -070010823 if (TRUE == pHddCtx->tmInfo.tmAction.enterImps)
10824 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053010825 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070010826 "%s: MAX TM Level Scan not allowed", __func__);
10827 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010828 return -EBUSY;
Jeff Johnson295189b2012-06-20 16:38:30 -070010829 }
10830 mutex_unlock(&pHddCtx->tmInfo.tmOperationLock);
10831
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010832 /* Check if scan is allowed at this point of time.
10833 */
Padma, Santhosh Kumar98f271d2014-12-31 17:23:31 +053010834 if (hdd_isConnectionInProgress(pHddCtx))
Madan Mohan Koyyalamudicfd53742013-01-11 15:29:03 -080010835 {
10836 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Scan not allowed", __func__);
10837 return -EBUSY;
10838 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053010839
Jeff Johnson295189b2012-06-20 16:38:30 -070010840 vos_mem_zero( &scanRequest, sizeof(scanRequest));
10841
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010842 /* Even though supplicant doesn't provide any SSIDs, n_ssids is set to 1.
10843 * Becasue of this, driver is assuming that this is not wildcard scan and so
10844 * is not aging out the scan results.
10845 */
10846 if (request->ssids && '\0' == request->ssids->ssid[0])
Jeff Johnson295189b2012-06-20 16:38:30 -070010847 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010848 request->n_ssids = 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070010849 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010850
10851 if ((request->ssids) && (0 < request->n_ssids))
10852 {
10853 tCsrSSIDInfo *SsidInfo;
10854 int j;
10855 scanRequest.SSIDs.numOfSSIDs = request->n_ssids;
10856 /* Allocate num_ssid tCsrSSIDInfo structure */
10857 SsidInfo = scanRequest.SSIDs.SSIDList =
10858 ( tCsrSSIDInfo *)vos_mem_malloc(
10859 request->n_ssids*sizeof(tCsrSSIDInfo));
10860
10861 if(NULL == scanRequest.SSIDs.SSIDList)
10862 {
10863 hddLog(VOS_TRACE_LEVEL_ERROR,
10864 "%s: memory alloc failed SSIDInfo buffer", __func__);
10865 return -ENOMEM;
10866 }
10867
10868 /* copy all the ssid's and their length */
10869 for(j = 0; j < request->n_ssids; j++, SsidInfo++)
10870 {
10871 /* get the ssid length */
10872 SsidInfo->SSID.length = request->ssids[j].ssid_len;
10873 vos_mem_copy(SsidInfo->SSID.ssId, &request->ssids[j].ssid[0],
10874 SsidInfo->SSID.length);
10875 SsidInfo->SSID.ssId[SsidInfo->SSID.length] = '\0';
10876 hddLog(VOS_TRACE_LEVEL_INFO, "SSID number %d: %s",
10877 j, SsidInfo->SSID.ssId);
10878 }
10879 /* set the scan type to active */
10880 scanRequest.scanType = eSIR_ACTIVE_SCAN;
10881 }
10882 else if(WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070010883 {
Siddharth Bhal0c162d02014-05-06 19:50:42 +053010884 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
10885 TRACE_CODE_HDD_CFG80211_SCAN,
10886 pAdapter->sessionId, 0));
Jeff Johnson295189b2012-06-20 16:38:30 -070010887 /* set the scan type to active */
10888 scanRequest.scanType = eSIR_ACTIVE_SCAN;
Jeff Johnson295189b2012-06-20 16:38:30 -070010889 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010890 else
10891 {
10892 /*Set the scan type to default type, in this case it is ACTIVE*/
10893 scanRequest.scanType = pScanInfo->scan_mode;
10894 }
10895 scanRequest.minChnTime = cfg_param->nActiveMinChnTime;
10896 scanRequest.maxChnTime = cfg_param->nActiveMaxChnTime;
Jeff Johnson295189b2012-06-20 16:38:30 -070010897
10898 /* set BSSType to default type */
10899 scanRequest.BSSType = eCSR_BSS_TYPE_ANY;
10900
10901 /*TODO: scan the requested channels only*/
10902
10903 /*Right now scanning all the channels */
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010904 if (MAX_CHANNEL < request->n_channels)
Jeff Johnson295189b2012-06-20 16:38:30 -070010905 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010906 hddLog(VOS_TRACE_LEVEL_WARN,
10907 "No of Scan Channels exceeded limit: %d", request->n_channels);
10908 request->n_channels = MAX_CHANNEL;
10909 }
10910
10911 hddLog(VOS_TRACE_LEVEL_INFO,
10912 "No of Scan Channels: %d", request->n_channels);
10913
10914
10915 if( request->n_channels )
10916 {
10917 char chList [(request->n_channels*5)+1];
10918 int len;
10919 channelList = vos_mem_malloc( request->n_channels );
10920 if( NULL == channelList )
c_hpothu53512302014-04-15 18:49:53 +053010921 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010922 hddLog(VOS_TRACE_LEVEL_ERROR,
10923 "%s: memory alloc failed channelList", __func__);
10924 status = -ENOMEM;
10925 goto free_mem;
c_hpothu53512302014-04-15 18:49:53 +053010926 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010927
10928 for( i = 0, len = 0; i < request->n_channels ; i++ )
10929 {
10930 channelList[i] = request->channels[i]->hw_value;
10931 len += snprintf(chList+len, 5, "%d ", channelList[i]);
10932 }
10933
Nirav Shah20ac06f2013-12-12 18:14:06 +053010934 hddLog(VOS_TRACE_LEVEL_INFO,
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010935 "Channel-List: %s ", chList);
10936 }
c_hpothu53512302014-04-15 18:49:53 +053010937
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010938 scanRequest.ChannelInfo.numOfChannels = request->n_channels;
10939 scanRequest.ChannelInfo.ChannelList = channelList;
10940
10941 /* set requestType to full scan */
10942 scanRequest.requestType = eCSR_SCAN_REQUEST_FULL_SCAN;
10943
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010944 /* if there is back to back scan happening in driver with in
10945 * nDeferScanTimeInterval interval driver should defer new scan request
10946 * and should provide last cached scan results instead of new channel list.
10947 * This rule is not applicable if scan is p2p scan.
10948 * This condition will work only in case when last request no of channels
10949 * and channels are exactly same as new request.
Agarwal Ashish57e84372014-12-05 18:26:53 +053010950 * This should be done only in connected state
Sushant Kaushik86592172015-04-27 16:35:03 +053010951 * Scan shouldn't be defered for WPS scan case.
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010952 */
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010953
Sushant Kaushik86592172015-04-27 16:35:03 +053010954 pWpsIe = wlan_hdd_get_wps_ie_ptr((v_U8_t*)request->ie,request->ie_len);
10955 /* if wps ie is NULL , then only defer scan */
10956 if ( pWpsIe == NULL &&
10957 (VOS_STATUS_SUCCESS == hdd_is_any_session_connected(pHddCtx)))
Agarwal Ashish57e84372014-12-05 18:26:53 +053010958 {
10959 if ( pScanInfo->last_scan_timestamp !=0 &&
10960 ((vos_timer_get_system_time() - pScanInfo->last_scan_timestamp ) < pHddCtx->cfg_ini->nDeferScanTimeInterval))
10961 {
10962 if ( request->no_cck == FALSE && scanRequest.ChannelInfo.numOfChannels != 1 &&
10963 (pScanInfo->last_scan_numChannels == scanRequest.ChannelInfo.numOfChannels) &&
10964 vos_mem_compare(pScanInfo->last_scan_channelList,
10965 channelList, pScanInfo->last_scan_numChannels))
10966 {
10967 hddLog(VOS_TRACE_LEVEL_WARN,
10968 " New and old station scan time differ is less then %u",
10969 pHddCtx->cfg_ini->nDeferScanTimeInterval);
10970
10971 ret = wlan_hdd_cfg80211_update_bss((WLAN_HDD_GET_CTX(pAdapter))->wiphy,
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010972 pAdapter);
10973
Agarwal Ashish57e84372014-12-05 18:26:53 +053010974 hddLog(VOS_TRACE_LEVEL_WARN,
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010975 "Return old cached scan as all channels and no of channels are same");
10976
Agarwal Ashish57e84372014-12-05 18:26:53 +053010977 if (0 > ret)
10978 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010979
Agarwal Ashish57e84372014-12-05 18:26:53 +053010980 cfg80211_scan_done(request, eCSR_SCAN_SUCCESS);
Masti, Narayanraddide03eb02015-02-06 11:23:50 +053010981
10982 status = eHAL_STATUS_SUCCESS;
10983 goto free_mem;
Agarwal Ashish57e84372014-12-05 18:26:53 +053010984 }
10985 }
Agarwal Ashishbd3e10b2014-11-24 19:19:46 +053010986 }
10987
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053010988 /* Flush the scan results(only p2p beacons) for STA scan and P2P
10989 * search (Flush on both full scan and social scan but not on single
10990 * channel scan).P2P search happens on 3 social channels (1, 6, 11)
10991 */
10992
10993 /* Supplicant does single channel scan after 8-way handshake
10994 * and in that case driver shoudnt flush scan results. If
10995 * driver flushes the scan results here and unfortunately if
10996 * the AP doesnt respond to our probe req then association
10997 * fails which is not desired
10998 */
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053010999 if ((request->n_ssids == 1)
11000 && (request->ssids != NULL)
11001 && vos_mem_compare(&request->ssids[0], "DIRECT-", 7))
11002 is_p2p_scan = true;
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011003
Deepthi Gowrid5c5c2b2015-06-11 17:00:46 +053011004 if( is_p2p_scan ||
11005 (request->n_channels != WLAN_HDD_P2P_SINGLE_CHANNEL_SCAN) )
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011006 {
11007 hddLog(VOS_TRACE_LEVEL_DEBUG, "Flushing P2P Results");
11008 sme_ScanFlushP2PResult( WLAN_HDD_GET_HAL_CTX(pAdapter),
11009 pAdapter->sessionId );
11010 }
11011
11012 if( request->ie_len )
11013 {
11014 /* save this for future association (join requires this) */
11015 /*TODO: Array needs to be converted to dynamic allocation,
11016 * as multiple ie.s can be sent in cfg80211_scan_request structure
11017 * CR 597966
11018 */
11019 memset( &pScanInfo->scanAddIE, 0, sizeof(pScanInfo->scanAddIE) );
11020 memcpy( pScanInfo->scanAddIE.addIEdata, request->ie, request->ie_len);
11021 pScanInfo->scanAddIE.length = request->ie_len;
11022
11023 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11024 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) ||
11025 (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011026 {
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011027 if (request->ie_len <= SIR_MAC_MAX_ADD_IE_LENGTH)
Jeff Johnson295189b2012-06-20 16:38:30 -070011028 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011029 pwextBuf->roamProfile.nAddIEScanLength = request->ie_len;
11030 memcpy( pwextBuf->roamProfile.addIEScan,
11031 request->ie, request->ie_len);
11032 }
11033 else
11034 {
11035 hddLog(VOS_TRACE_LEVEL_ERROR, "Scan Ie length is invalid:"
11036 "%zu", request->ie_len);
Jeff Johnson295189b2012-06-20 16:38:30 -070011037 }
11038
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011039 }
11040 scanRequest.uIEFieldLen = pScanInfo->scanAddIE.length;
11041 scanRequest.pIEField = pScanInfo->scanAddIE.addIEdata;
11042
11043 pP2pIe = wlan_hdd_get_p2p_ie_ptr((v_U8_t*)request->ie,
11044 request->ie_len);
11045 if (pP2pIe != NULL)
11046 {
11047#ifdef WLAN_FEATURE_P2P_DEBUG
11048 if (((globalP2PConnectionStatus == P2P_GO_NEG_COMPLETED) ||
11049 (globalP2PConnectionStatus == P2P_GO_NEG_PROCESS)) &&
11050 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Nirav Shah20ac06f2013-12-12 18:14:06 +053011051 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011052 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_1;
11053 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11054 "Go nego completed to Connection is started");
11055 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11056 "for 8way Handshake");
Nirav Shah20ac06f2013-12-12 18:14:06 +053011057 }
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011058 else if((globalP2PConnectionStatus == P2P_CLIENT_DISCONNECTED_STATE) &&
11059 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Jeff Johnson295189b2012-06-20 16:38:30 -070011060 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011061 globalP2PConnectionStatus = P2P_CLIENT_CONNECTING_STATE_2;
11062 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P State] Changing state from "
11063 "Disconnected state to Connection is started");
11064 hddLog(VOS_TRACE_LEVEL_ERROR,"[P2P]P2P Scanning is started "
11065 "for 4way Handshake");
11066 }
11067#endif
11068
11069 /* no_cck will be set during p2p find to disable 11b rates */
11070 if(TRUE == request->no_cck)
11071 {
11072 hddLog(VOS_TRACE_LEVEL_INFO,
11073 "%s: This is a P2P Search", __func__);
11074 scanRequest.p2pSearch = 1;
11075
11076 if( request->n_channels == WLAN_HDD_P2P_SOCIAL_CHANNELS )
Agarwal Ashish4f616132013-12-30 23:32:50 +053011077 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011078 /* set requestType to P2P Discovery */
11079 scanRequest.requestType = eCSR_SCAN_P2P_DISCOVERY;
11080 }
11081
11082 /*
11083 Skip Dfs Channel in case of P2P Search
11084 if it is set in ini file
11085 */
11086 if(cfg_param->skipDfsChnlInP2pSearch)
11087 {
11088 scanRequest.skipDfsChnlInP2pSearch = 1;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011089 }
11090 else
11091 {
Padma, Santhosh Kumar787bd5c2014-05-15 20:09:31 +053011092 scanRequest.skipDfsChnlInP2pSearch = 0;
Agarwal Ashish4f616132013-12-30 23:32:50 +053011093 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011094
Agarwal Ashish4f616132013-12-30 23:32:50 +053011095 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011096 }
11097 }
11098
11099 INIT_COMPLETION(pScanInfo->scan_req_completion_event);
11100
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011101#ifdef FEATURE_WLAN_TDLS
11102 /* if tdls disagree scan right now, return immediately.
11103 tdls will schedule the scan when scan is allowed. (return SUCCESS)
11104 or will reject the scan if any TDLS is in progress. (return -EBUSY)
11105 */
11106 status = wlan_hdd_tdls_scan_callback (pAdapter,
11107 wiphy,
11108#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11109 dev,
11110#endif
11111 request);
11112 if(status <= 0)
11113 {
11114 if(!status)
11115 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS in progress."
11116 "scan rejected %d", __func__, status);
11117 else
11118 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: TDLS teardown is ongoing %d",
11119 __func__, status);
11120
11121 return status;
11122 }
11123#endif
11124
Madan Mohan Koyyalamudi9f5a10c2012-09-28 14:46:16 -070011125 /* acquire the wakelock to avoid the apps suspend during the scan. To
11126 * address the following issues.
11127 * 1) Disconnected scenario: we are not allowing the suspend as WLAN is not in
11128 * BMPS/IMPS this result in android trying to suspend aggressively and backing off
11129 * for long time, this result in apps running at full power for long time.
11130 * 2) Connected scenario: If we allow the suspend during the scan, RIVA will
11131 * be stuck in full power because of resume BMPS
11132 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011133 hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Jeff Johnsone7245742012-09-05 17:12:55 -070011134
Nirav Shah20ac06f2013-12-12 18:14:06 +053011135 hddLog(VOS_TRACE_LEVEL_INFO_HIGH,
11136 "requestType %d, scanType %d, minChnTime %d, maxChnTime %d,"
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053011137 "p2pSearch %d, skipDfsChnlInP2pSearch %d",
11138 scanRequest.requestType, scanRequest.scanType,
11139 scanRequest.minChnTime, scanRequest.maxChnTime,
Nirav Shah20ac06f2013-12-12 18:14:06 +053011140 scanRequest.p2pSearch, scanRequest.skipDfsChnlInP2pSearch);
11141
Siddharth Bhal76972212014-10-15 16:22:51 +053011142 if (pHddCtx->spoofMacAddr.isEnabled)
11143 {
11144 hddLog(VOS_TRACE_LEVEL_INFO,
11145 "%s: MAC Spoofing enabled for current scan", __func__);
11146 /* Updating SelfSta Mac Addr in TL which will be used to get staidx
11147 * to fill TxBds for probe request during current scan
11148 */
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011149 status = WLANTL_updateSpoofMacAddr(pHddCtx->pvosContext,
Siddharth Bhal76972212014-10-15 16:22:51 +053011150 &pHddCtx->spoofMacAddr.randomMacAddr, &pAdapter->macAddressCurrent);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011151
11152 if(status != VOS_STATUS_SUCCESS)
11153 {
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011154 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011155 status = -EFAULT;
Ganesh Kondabattini6d3b4902015-05-12 23:19:22 +053011156#ifdef FEATURE_WLAN_TDLS
11157 wlan_hdd_tdls_scan_done_callback(pAdapter);
11158#endif
Padma, Santhosh Kumar79236142015-02-09 18:19:33 +053011159 goto free_mem;
11160 }
Siddharth Bhal76972212014-10-15 16:22:51 +053011161 }
Mahesh A Saptasagar51dc36c2015-06-16 12:07:15 +053011162 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
Jeff Johnsone7245742012-09-05 17:12:55 -070011163 status = sme_ScanRequest( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011164 pAdapter->sessionId, &scanRequest, &scanId,
11165 &hdd_cfg80211_scan_done_callback, dev );
Jeff Johnsone7245742012-09-05 17:12:55 -070011166
Jeff Johnson295189b2012-06-20 16:38:30 -070011167 if (eHAL_STATUS_SUCCESS != status)
11168 {
11169 hddLog(VOS_TRACE_LEVEL_ERROR,
11170 "%s: sme_ScanRequest returned error %d", __func__, status);
11171 complete(&pScanInfo->scan_req_completion_event);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011172 if(eHAL_STATUS_RESOURCES == status)
11173 {
Nirav Shah20ac06f2013-12-12 18:14:06 +053011174 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: HO is in progress."
11175 "So defer the scan by informing busy",__func__);
Madan Mohan Koyyalamudi3b230fe2012-10-18 14:46:32 -070011176 status = -EBUSY;
11177 } else {
11178 status = -EIO;
11179 }
Sushant Kaushik83392fa2015-05-05 17:44:40 +053011180 hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_SCAN);
Pradeep Reddy POTTETIc7822df2015-02-19 20:15:41 +053011181
11182#ifdef FEATURE_WLAN_TDLS
11183 wlan_hdd_tdls_scan_done_callback(pAdapter);
11184#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011185 goto free_mem;
11186 }
11187
11188 pScanInfo->mScanPending = TRUE;
Kaushik, Sushant4975a572014-10-21 16:07:48 +053011189 pScanInfo->sessionId = pAdapter->sessionId;
Jeff Johnson295189b2012-06-20 16:38:30 -070011190 pAdapter->request = request;
11191 pScanInfo->scanId = scanId;
11192
11193 complete(&pScanInfo->scan_req_completion_event);
11194
11195free_mem:
11196 if( scanRequest.SSIDs.SSIDList )
11197 {
11198 vos_mem_free(scanRequest.SSIDs.SSIDList);
11199 }
11200
11201 if( channelList )
11202 vos_mem_free( channelList );
11203
11204 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011205 return status;
11206}
11207
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053011208int wlan_hdd_cfg80211_scan( struct wiphy *wiphy,
11209#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11210 struct net_device *dev,
11211#endif
11212 struct cfg80211_scan_request *request)
11213{
11214 int ret;
11215
11216 vos_ssr_protect(__func__);
11217 ret = __wlan_hdd_cfg80211_scan(wiphy,
11218#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
11219 dev,
11220#endif
11221 request);
11222 vos_ssr_unprotect(__func__);
11223
11224 return ret;
11225}
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011226
11227void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel)
11228{
11229 v_U8_t iniDot11Mode =
11230 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->dot11Mode;
11231 eHddDot11Mode hddDot11Mode = iniDot11Mode;
11232
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011233 hddLog(LOG1, FL("Channel Bonding Mode Selected is %u"),
11234 iniDot11Mode);
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011235 switch ( iniDot11Mode )
11236 {
11237 case eHDD_DOT11_MODE_AUTO:
11238 case eHDD_DOT11_MODE_11ac:
11239 case eHDD_DOT11_MODE_11ac_ONLY:
11240#ifdef WLAN_FEATURE_11AC
Abhishek Singh4b1d2352014-08-01 21:59:28 +053011241 if ( sme_IsFeatureSupportedByDriver(DOT11AC) &&
11242 sme_IsFeatureSupportedByFW(DOT11AC) )
11243 hddDot11Mode = eHDD_DOT11_MODE_11ac;
11244 else
11245 hddDot11Mode = eHDD_DOT11_MODE_11n;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011246#else
11247 hddDot11Mode = eHDD_DOT11_MODE_11n;
11248#endif
11249 break;
11250 case eHDD_DOT11_MODE_11n:
11251 case eHDD_DOT11_MODE_11n_ONLY:
11252 hddDot11Mode = eHDD_DOT11_MODE_11n;
11253 break;
11254 default:
11255 hddDot11Mode = iniDot11Mode;
11256 break;
11257 }
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011258#ifdef WLAN_FEATURE_AP_HT40_24G
11259 if (operationChannel > SIR_11B_CHANNEL_END)
11260#endif
11261 {
11262 /* This call decides required channel bonding mode */
11263 sme_SelectCBMode((WLAN_HDD_GET_CTX(pAdapter)->hHal),
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011264 hdd_cfg_xlate_to_csr_phy_mode(hddDot11Mode),
11265 operationChannel);
Hardik Kantilal Patel086e0a32014-11-20 14:56:26 +053011266 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011267}
11268
Jeff Johnson295189b2012-06-20 16:38:30 -070011269/*
11270 * FUNCTION: wlan_hdd_cfg80211_connect_start
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011271 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070011272 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011273int wlan_hdd_cfg80211_connect_start( hdd_adapter_t *pAdapter,
Jeff Johnson32d95a32012-09-10 13:15:23 -070011274 const u8 *ssid, size_t ssid_len, const u8 *bssid, u8 operatingChannel)
Jeff Johnson295189b2012-06-20 16:38:30 -070011275{
11276 int status = 0;
11277 hdd_wext_state_t *pWextState;
Yue Mae36e3552014-03-05 17:06:20 -080011278 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070011279 v_U32_t roamId;
11280 tCsrRoamProfile *pRoamProfile;
Jeff Johnson295189b2012-06-20 16:38:30 -070011281 eCsrAuthType RSNAuthType;
11282
11283 ENTER();
11284
11285 pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Yue Mae36e3552014-03-05 17:06:20 -080011286 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
11287
11288 status = wlan_hdd_validate_context(pHddCtx);
11289 if (status)
11290 {
Yue Mae36e3552014-03-05 17:06:20 -080011291 return status;
11292 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011293
Jeff Johnson295189b2012-06-20 16:38:30 -070011294 if (SIR_MAC_MAX_SSID_LENGTH < ssid_len)
11295 {
11296 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: wrong SSID len", __func__);
11297 return -EINVAL;
11298 }
11299
11300 pRoamProfile = &pWextState->roamProfile;
11301
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011302 if (pRoamProfile)
Jeff Johnson295189b2012-06-20 16:38:30 -070011303 {
Jeff Johnsone7245742012-09-05 17:12:55 -070011304 hdd_station_ctx_t *pHddStaCtx;
11305 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011306
Siddharth Bhalda0d1622015-04-24 15:47:49 +053011307 wlan_hdd_get_frame_logs(pAdapter, WLAN_HDD_GET_FRAME_LOG_CMD_CLEAR);
11308
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011309 if (HDD_WMM_USER_MODE_NO_QOS ==
Jeff Johnson295189b2012-06-20 16:38:30 -070011310 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->WmmMode)
11311 {
11312 /*QoS not enabled in cfg file*/
11313 pRoamProfile->uapsd_mask = 0;
11314 }
11315 else
11316 {
11317 /*QoS enabled, update uapsd mask from cfg file*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011318 pRoamProfile->uapsd_mask =
Jeff Johnson295189b2012-06-20 16:38:30 -070011319 (WLAN_HDD_GET_CTX(pAdapter))->cfg_ini->UapsdMask;
11320 }
11321
11322 pRoamProfile->SSIDs.numOfSSIDs = 1;
11323 pRoamProfile->SSIDs.SSIDList->SSID.length = ssid_len;
11324 vos_mem_zero(pRoamProfile->SSIDs.SSIDList->SSID.ssId,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011325 sizeof(pRoamProfile->SSIDs.SSIDList->SSID.ssId));
Jeff Johnson295189b2012-06-20 16:38:30 -070011326 vos_mem_copy((void *)(pRoamProfile->SSIDs.SSIDList->SSID.ssId),
11327 ssid, ssid_len);
11328
11329 if (bssid)
11330 {
11331 pRoamProfile->BSSIDs.numOfBSSIDs = 1;
11332 vos_mem_copy((void *)(pRoamProfile->BSSIDs.bssid), bssid,
11333 WNI_CFG_BSSID_LEN);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011334 /* Save BSSID in seperate variable as well, as RoamProfile
11335 BSSID is getting zeroed out in the association process. And in
Jeff Johnson295189b2012-06-20 16:38:30 -070011336 case of join failure we should send valid BSSID to supplicant
11337 */
11338 vos_mem_copy((void *)(pWextState->req_bssId), bssid,
11339 WNI_CFG_BSSID_LEN);
11340 }
Dhanashri Atre51981c62013-06-13 11:47:57 -070011341 else
11342 {
11343 vos_mem_zero((void *)(pRoamProfile->BSSIDs.bssid),WNI_CFG_BSSID_LEN);
11344 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011345
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011346 hddLog(LOG1, FL("Connect to SSID: %s opertating Channel: %u"),
11347 pRoamProfile->SSIDs.SSIDList->SSID.ssId, operatingChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070011348 if ((IW_AUTH_WPA_VERSION_WPA == pWextState->wpaVersion) ||
11349 (IW_AUTH_WPA_VERSION_WPA2 == pWextState->wpaVersion))
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011350 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011351 /*set gen ie*/
11352 hdd_SetGENIEToCsr(pAdapter, &RSNAuthType);
11353 /*set auth*/
11354 hdd_set_csr_auth_type(pAdapter, RSNAuthType);
11355 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011356#ifdef FEATURE_WLAN_WAPI
11357 if (pAdapter->wapi_info.nWapiMode)
11358 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011359 hddLog(LOG1, "%s: Setting WAPI AUTH Type and Encryption Mode values", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011360 switch (pAdapter->wapi_info.wapiAuthMode)
11361 {
11362 case WAPI_AUTH_MODE_PSK:
11363 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011364 hddLog(LOG1, "%s: WAPI AUTH TYPE: PSK: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011365 pAdapter->wapi_info.wapiAuthMode);
11366 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_PSK;
11367 break;
11368 }
11369 case WAPI_AUTH_MODE_CERT:
11370 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011371 hddLog(LOG1, "%s: WAPI AUTH TYPE: CERT: %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011372 pAdapter->wapi_info.wapiAuthMode);
11373 pRoamProfile->AuthType.authType[0] = eCSR_AUTH_TYPE_WAPI_WAI_CERTIFICATE;
11374 break;
11375 }
11376 } // End of switch
11377 if ( pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_PSK ||
11378 pAdapter->wapi_info.wapiAuthMode == WAPI_AUTH_MODE_CERT)
11379 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070011380 hddLog(LOG1, "%s: WAPI PAIRWISE/GROUP ENCRYPTION: WPI", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070011381 pRoamProfile->AuthType.numEntries = 1;
11382 pRoamProfile->EncryptionType.numEntries = 1;
11383 pRoamProfile->EncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11384 pRoamProfile->mcEncryptionType.numEntries = 1;
11385 pRoamProfile->mcEncryptionType.encryptionType[0] = eCSR_ENCRYPT_TYPE_WPI;
11386 }
11387 }
11388#endif /* FEATURE_WLAN_WAPI */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011389#ifdef WLAN_FEATURE_GTK_OFFLOAD
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011390 /* Initializing gtkOffloadReqParams */
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011391 if ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) ||
11392 (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
11393 {
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053011394 memset(&pHddStaCtx->gtkOffloadReqParams, 0,
11395 sizeof (tSirGtkOffloadParams));
11396 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_DISABLE;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053011397 }
11398#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011399 pRoamProfile->csrPersona = pAdapter->device_mode;
11400
Jeff Johnson32d95a32012-09-10 13:15:23 -070011401 if( operatingChannel )
11402 {
11403 pRoamProfile->ChannelInfo.ChannelList = &operatingChannel;
11404 pRoamProfile->ChannelInfo.numOfChannels = 1;
11405 }
Chet Lanctot186b5732013-03-18 10:26:30 -070011406 else
11407 {
11408 pRoamProfile->ChannelInfo.ChannelList = NULL;
11409 pRoamProfile->ChannelInfo.numOfChannels = 0;
11410 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070011411 if ( (WLAN_HDD_IBSS == pAdapter->device_mode) && operatingChannel)
11412 {
11413 hdd_select_cbmode(pAdapter,operatingChannel);
11414 }
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053011415
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011416 /* change conn_state to connecting before sme_RoamConnect(), because sme_RoamConnect()
11417 * has a direct path to call hdd_smeRoamCallback(), which will change the conn_state
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011418 * If direct path, conn_state will be accordingly changed to NotConnected or Associated
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011419 * by either hdd_AssociationCompletionHandler() or hdd_DisConnectHandler() in sme_RoamCallback()
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011420 * if sme_RomConnect is to be queued, Connecting state will remain until it is completed.
11421 */
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011422 if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11423 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode)
Abhishek Singhf4669da2014-05-26 15:07:49 +053011424 {
11425 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
11426 "%s: Set HDD connState to eConnectionState_Connecting",
11427 __func__);
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011428 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
11429 eConnectionState_Connecting);
Abhishek Singhf4669da2014-05-26 15:07:49 +053011430 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011431 status = sme_RoamConnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
Jeff Johnson295189b2012-06-20 16:38:30 -070011432 pAdapter->sessionId, pRoamProfile, &roamId);
11433
Gopichand Nakkalaa3c8fb62013-06-21 15:36:42 +053011434 if ((eHAL_STATUS_SUCCESS != status) &&
11435 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode ||
11436 WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011437
11438 {
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011439 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: sme_RoamConnect (session %d) failed with "
11440 "status %d. -> NotConnected", __func__, pAdapter->sessionId, status);
11441 /* change back to NotAssociated */
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011442 hdd_connSetConnectionState(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter),
Madan Mohan Koyyalamudi42dcd162012-12-03 16:34:04 -080011443 eConnectionState_NotConnected);
Madan Mohan Koyyalamudid5acbf52012-11-28 01:45:08 +053011444 }
Madan Mohan Koyyalamudidf86c422012-12-04 17:03:44 -080011445
11446 pRoamProfile->ChannelInfo.ChannelList = NULL;
11447 pRoamProfile->ChannelInfo.numOfChannels = 0;
11448
Jeff Johnson295189b2012-06-20 16:38:30 -070011449 }
11450 else
11451 {
11452 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid Roam profile", __func__);
11453 return -EINVAL;
11454 }
Madan Mohan Koyyalamudifd4e1da2012-11-09 17:50:19 -080011455 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070011456 return status;
11457}
11458
11459/*
11460 * FUNCTION: wlan_hdd_set_cfg80211_auth_type
11461 * This function is used to set the authentication type (OPEN/SHARED).
11462 *
11463 */
11464static int wlan_hdd_cfg80211_set_auth_type(hdd_adapter_t *pAdapter,
11465 enum nl80211_auth_type auth_type)
11466{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011467 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011468 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11469
11470 ENTER();
11471
11472 /*set authentication type*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011473 switch (auth_type)
Jeff Johnson295189b2012-06-20 16:38:30 -070011474 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011475 case NL80211_AUTHTYPE_AUTOMATIC:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011476 hddLog(VOS_TRACE_LEVEL_INFO,
11477 "%s: set authentication type to AUTOSWITCH", __func__);
11478 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_AUTOSWITCH;
11479 break;
11480
11481 case NL80211_AUTHTYPE_OPEN_SYSTEM:
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070011482#ifdef WLAN_FEATURE_VOWIFI_11R
11483 case NL80211_AUTHTYPE_FT:
11484#endif /* WLAN_FEATURE_VOWIFI_11R */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011485 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011486 "%s: set authentication type to OPEN", __func__);
11487 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_OPEN_SYSTEM;
11488 break;
11489
11490 case NL80211_AUTHTYPE_SHARED_KEY:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011491 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011492 "%s: set authentication type to SHARED", __func__);
11493 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_SHARED_KEY;
11494 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011495#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011496 case NL80211_AUTHTYPE_NETWORK_EAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011497 hddLog(VOS_TRACE_LEVEL_INFO,
Jeff Johnson295189b2012-06-20 16:38:30 -070011498 "%s: set authentication type to CCKM WPA", __func__);
11499 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_CCKM_WPA;//eCSR_AUTH_TYPE_CCKM_RSN needs to be handled as well if required.
11500 break;
11501#endif
11502
11503
11504 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011505 hddLog(VOS_TRACE_LEVEL_ERROR,
11506 "%s: Unsupported authentication type %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070011507 auth_type);
11508 pHddStaCtx->conn_info.authType = eCSR_AUTH_TYPE_UNKNOWN;
11509 return -EINVAL;
11510 }
11511
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011512 pWextState->roamProfile.AuthType.authType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011513 pHddStaCtx->conn_info.authType;
11514 return 0;
11515}
11516
11517/*
11518 * FUNCTION: wlan_hdd_set_akm_suite
11519 * This function is used to set the key mgmt type(PSK/8021x).
11520 *
11521 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011522static int wlan_hdd_set_akm_suite( hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070011523 u32 key_mgmt
11524 )
11525{
11526 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
11527 ENTER();
Abhishek Singhae408032014-09-25 17:22:04 +053011528 /* Should be in ieee802_11_defs.h */
11529#define WLAN_AKM_SUITE_8021X_SHA256 0x000FAC05
11530#define WLAN_AKM_SUITE_PSK_SHA256 0x000FAC06
Jeff Johnson295189b2012-06-20 16:38:30 -070011531 /*set key mgmt type*/
11532 switch(key_mgmt)
11533 {
11534 case WLAN_AKM_SUITE_PSK:
Abhishek Singhae408032014-09-25 17:22:04 +053011535 case WLAN_AKM_SUITE_PSK_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011536#ifdef WLAN_FEATURE_VOWIFI_11R
11537 case WLAN_AKM_SUITE_FT_PSK:
11538#endif
11539 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to PSK",
Jeff Johnson295189b2012-06-20 16:38:30 -070011540 __func__);
11541 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_PSK;
11542 break;
11543
11544 case WLAN_AKM_SUITE_8021X:
Abhishek Singhae408032014-09-25 17:22:04 +053011545 case WLAN_AKM_SUITE_8021X_SHA256:
Gopichand Nakkala356fb102013-03-06 12:34:04 +053011546#ifdef WLAN_FEATURE_VOWIFI_11R
11547 case WLAN_AKM_SUITE_FT_8021X:
11548#endif
11549 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to 8021x",
Jeff Johnson295189b2012-06-20 16:38:30 -070011550 __func__);
11551 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11552 break;
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011553#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011554#define WLAN_AKM_SUITE_CCKM 0x00409600 /* Should be in ieee802_11_defs.h */
11555#define IW_AUTH_KEY_MGMT_CCKM 8 /* Should be in linux/wireless.h */
11556 case WLAN_AKM_SUITE_CCKM:
11557 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to CCKM",
11558 __func__);
11559 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_CCKM;
11560 break;
11561#endif
Leela Venkata Kiran Kumar Reddy Chiralae208a832014-04-27 22:34:25 -070011562#ifndef WLAN_AKM_SUITE_OSEN
11563#define WLAN_AKM_SUITE_OSEN 0x506f9a01 /* Should be in ieee802_11_defs.h */
11564 case WLAN_AKM_SUITE_OSEN:
11565 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting key mgmt type to OSEN",
11566 __func__);
11567 pWextState->authKeyMgmt |= IW_AUTH_KEY_MGMT_802_1X;
11568 break;
11569#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011570
11571 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011572 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported key mgmt type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011573 __func__, key_mgmt);
11574 return -EINVAL;
11575
11576 }
11577 return 0;
11578}
11579
11580/*
11581 * FUNCTION: wlan_hdd_cfg80211_set_cipher
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011582 * This function is used to set the encryption type
Jeff Johnson295189b2012-06-20 16:38:30 -070011583 * (NONE/WEP40/WEP104/TKIP/CCMP).
11584 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011585static int wlan_hdd_cfg80211_set_cipher( hdd_adapter_t *pAdapter,
11586 u32 cipher,
Jeff Johnson295189b2012-06-20 16:38:30 -070011587 bool ucast
11588 )
11589{
11590 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011591 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070011592 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
11593
11594 ENTER();
11595
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011596 if (!cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011597 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011598 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: received cipher %d - considering none",
Jeff Johnson295189b2012-06-20 16:38:30 -070011599 __func__, cipher);
11600 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11601 }
11602 else
11603 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011604
Jeff Johnson295189b2012-06-20 16:38:30 -070011605 /*set encryption method*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011606 switch (cipher)
Jeff Johnson295189b2012-06-20 16:38:30 -070011607 {
11608 case IW_AUTH_CIPHER_NONE:
11609 encryptionType = eCSR_ENCRYPT_TYPE_NONE;
11610 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011611
Jeff Johnson295189b2012-06-20 16:38:30 -070011612 case WLAN_CIPHER_SUITE_WEP40:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011613 encryptionType = eCSR_ENCRYPT_TYPE_WEP40;
Jeff Johnson295189b2012-06-20 16:38:30 -070011614 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011615
Jeff Johnson295189b2012-06-20 16:38:30 -070011616 case WLAN_CIPHER_SUITE_WEP104:
Gopichand Nakkala29149562013-05-10 21:43:41 +053011617 encryptionType = eCSR_ENCRYPT_TYPE_WEP104;
Jeff Johnson295189b2012-06-20 16:38:30 -070011618 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011619
Jeff Johnson295189b2012-06-20 16:38:30 -070011620 case WLAN_CIPHER_SUITE_TKIP:
11621 encryptionType = eCSR_ENCRYPT_TYPE_TKIP;
11622 break;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011623
Jeff Johnson295189b2012-06-20 16:38:30 -070011624 case WLAN_CIPHER_SUITE_CCMP:
11625 encryptionType = eCSR_ENCRYPT_TYPE_AES;
11626 break;
11627#ifdef FEATURE_WLAN_WAPI
11628 case WLAN_CIPHER_SUITE_SMS4:
11629 encryptionType = eCSR_ENCRYPT_TYPE_WPI;
11630 break;
11631#endif
11632
Varun Reddy Yeturu5d5e2c62014-02-27 13:31:29 -080011633#ifdef FEATURE_WLAN_ESE
Jeff Johnson295189b2012-06-20 16:38:30 -070011634 case WLAN_CIPHER_SUITE_KRK:
11635 encryptionType = eCSR_ENCRYPT_TYPE_KRK;
11636 break;
11637#endif
11638 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011639 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Unsupported cipher type %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011640 __func__, cipher);
11641 return -EOPNOTSUPP;
11642 }
11643 }
11644
11645 if (ucast)
11646 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011647 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting unicast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011648 __func__, encryptionType);
11649 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
11650 pWextState->roamProfile.EncryptionType.numEntries = 1;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011651 pWextState->roamProfile.EncryptionType.encryptionType[0] =
Jeff Johnson295189b2012-06-20 16:38:30 -070011652 encryptionType;
11653 }
11654 else
11655 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011656 hddLog(VOS_TRACE_LEVEL_INFO, "%s: setting mcast cipher type to %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070011657 __func__, encryptionType);
11658 pHddStaCtx->conn_info.mcEncryptionType = encryptionType;
11659 pWextState->roamProfile.mcEncryptionType.numEntries = 1;
11660 pWextState->roamProfile.mcEncryptionType.encryptionType[0] = encryptionType;
11661 }
11662
11663 return 0;
11664}
11665
11666
11667/*
11668 * FUNCTION: wlan_hdd_cfg80211_set_ie
11669 * This function is used to parse WPA/RSN IE's.
11670 */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011671int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011672#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11673 const u8 *ie,
11674#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011675 u8 *ie,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011676#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011677 size_t ie_len
11678 )
11679{
11680 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011681#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
11682 const u8 *genie = ie;
11683#else
Jeff Johnson295189b2012-06-20 16:38:30 -070011684 u8 *genie = ie;
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011685#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070011686 v_U16_t remLen = ie_len;
11687#ifdef FEATURE_WLAN_WAPI
11688 v_U32_t akmsuite[MAX_NUM_AKM_SUITES];
11689 u16 *tmp;
11690 v_U16_t akmsuiteCount;
11691 int *akmlist;
11692#endif
11693 ENTER();
11694
11695 /* clear previous assocAddIE */
11696 pWextState->assocAddIE.length = 0;
11697 pWextState->roamProfile.bWPSAssociation = VOS_FALSE;
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011698 pWextState->roamProfile.bOSENAssociation = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070011699
11700 while (remLen >= 2)
11701 {
11702 v_U16_t eLen = 0;
11703 v_U8_t elementId;
11704 elementId = *genie++;
11705 eLen = *genie++;
11706 remLen -= 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011707
Arif Hussain6d2a3322013-11-17 19:50:10 -080011708 hddLog(VOS_TRACE_LEVEL_INFO, "%s: IE[0x%X], LEN[%d]",
Jeff Johnson295189b2012-06-20 16:38:30 -070011709 __func__, elementId, eLen);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011710
11711 switch ( elementId )
Jeff Johnson295189b2012-06-20 16:38:30 -070011712 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011713 case DOT11F_EID_WPA:
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011714 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 -070011715 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011716 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070011717 "%s: Invalid WPA IE", __func__);
11718 return -EINVAL;
11719 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011720 else if (0 == memcmp(&genie[0], "\x00\x50\xf2\x04", 4))
Jeff Johnson295189b2012-06-20 16:38:30 -070011721 {
11722 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011723 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPS IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011724 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011725
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011726 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011727 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011728 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE. "
11729 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011730 VOS_ASSERT(0);
11731 return -ENOMEM;
11732 }
11733 // WSC IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11734 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11735 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011736
Jeff Johnson295189b2012-06-20 16:38:30 -070011737 pWextState->roamProfile.bWPSAssociation = VOS_TRUE;
11738 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11739 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11740 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011741 else if (0 == memcmp(&genie[0], "\x00\x50\xf2", 3))
11742 {
Jeff Johnson295189b2012-06-20 16:38:30 -070011743 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WPA IE (len %d)",__func__, eLen + 2);
11744 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11745 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2) /*ie_len*/);
11746 pWextState->roamProfile.pWPAReqIE = pWextState->WPARSNIE;
11747 pWextState->roamProfile.nWPAReqIELength = eLen + 2;//ie_len;
11748 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011749 else if ( (0 == memcmp(&genie[0], P2P_OUI_TYPE,
Kiet Lam8da98992013-11-21 15:59:07 +053011750 P2P_OUI_TYPE_SIZE)))
Jeff Johnson295189b2012-06-20 16:38:30 -070011751 {
11752 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011753 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set P2P IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011754 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011755
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011756 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011757 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011758 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11759 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011760 VOS_ASSERT(0);
11761 return -ENOMEM;
11762 }
11763 // P2P IE is saved to Additional IE ; it should be accumulated to handle WPS IE + P2P IE
11764 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11765 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011766
Jeff Johnson295189b2012-06-20 16:38:30 -070011767 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11768 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11769 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011770#ifdef WLAN_FEATURE_WFD
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011771 else if ( (0 == memcmp(&genie[0], WFD_OUI_TYPE,
11772 WFD_OUI_TYPE_SIZE))
Jeff Johnson295189b2012-06-20 16:38:30 -070011773 /*Consider WFD IE, only for P2P Client */
11774 && (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) )
11775 {
11776 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011777 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set WFD IE(len %d)",
Jeff Johnson295189b2012-06-20 16:38:30 -070011778 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011779
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011780 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Jeff Johnson295189b2012-06-20 16:38:30 -070011781 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011782 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11783 "Need bigger buffer space");
Jeff Johnson295189b2012-06-20 16:38:30 -070011784 VOS_ASSERT(0);
11785 return -ENOMEM;
11786 }
11787 // WFD IE is saved to Additional IE ; it should be accumulated to handle
11788 // WPS IE + P2P IE + WFD IE
11789 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11790 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011791
Jeff Johnson295189b2012-06-20 16:38:30 -070011792 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11793 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11794 }
11795#endif
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011796 /* Appending HS 2.0 Indication Element in Assiciation Request */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011797 else if ( (0 == memcmp(&genie[0], HS20_OUI_TYPE,
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011798 HS20_OUI_TYPE_SIZE)) )
11799 {
11800 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011801 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set HS20 IE(len %d)",
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011802 __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) )
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011805 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011806 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11807 "Need bigger buffer space");
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011808 VOS_ASSERT(0);
11809 return -ENOMEM;
11810 }
11811 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11812 pWextState->assocAddIE.length += eLen + 2;
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011813
Madan Mohan Koyyalamudi1bed5982012-10-22 14:38:06 -070011814 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11815 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11816 }
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011817 /* Appending OSEN Information Element in Assiciation Request */
11818 else if ( (0 == memcmp(&genie[0], OSEN_OUI_TYPE,
11819 OSEN_OUI_TYPE_SIZE)) )
11820 {
11821 v_U16_t curAddIELen = pWextState->assocAddIE.length;
11822 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set OSEN IE(len %d)",
11823 __func__, eLen + 2);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011824
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011825 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Leela Venkata Kiran Kumar Reddy Chiralaf257bef2014-04-11 18:48:12 -070011826 {
11827 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11828 "Need bigger buffer space");
11829 VOS_ASSERT(0);
11830 return -ENOMEM;
11831 }
11832 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11833 pWextState->assocAddIE.length += eLen + 2;
11834
11835 pWextState->roamProfile.bOSENAssociation = VOS_TRUE;
11836 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11837 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11838 }
11839
Abhishek Singh4322e622015-06-10 15:42:54 +053011840 /* Update only for WPA IE */
11841 if (!memcmp(genie, WPA_OUI_TYPE, WPA_OUI_TYPE_SIZE) &&
11842 (WLAN_HDD_IBSS == pAdapter->device_mode)) {
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070011843
11844 /* populating as ADDIE in beacon frames */
11845 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053011846 WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, (u8 *)genie - 2, eLen + 2,
Praveen Kumar Sirisilla7d68b7b2013-09-22 14:01:42 -070011847 NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS)
11848 {
11849 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11850 WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL,
11851 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11852 {
11853 hddLog(LOGE,
11854 "Coldn't pass "
11855 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM");
11856 }
11857 }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/
11858 else
11859 hddLog(LOGE,
11860 "Could not pass on "
11861 "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM");
11862
11863 /* IBSS mode doesn't contain params->proberesp_ies still
11864 beaconIE's need to be populated in probe response frames */
11865 if ( (NULL != (genie - 2)) && (0 != eLen + 2) )
11866 {
11867 u16 rem_probe_resp_ie_len = eLen + 2;
11868 u8 probe_rsp_ie_len[3] = {0};
11869 u8 counter = 0;
11870
11871 /* Check Probe Resp Length if it is greater then 255 then
11872 Store Probe Rsp IEs into WNI_CFG_PROBE_RSP_ADDNIE_DATA1
11873 & WNI_CFG_PROBE_RSP_ADDNIE_DATA2 CFG Variable As We are
11874 not able Store More then 255 bytes into One Variable */
11875
11876 while ((rem_probe_resp_ie_len > 0) && (counter < 3))
11877 {
11878 if (rem_probe_resp_ie_len > MAX_CFG_STRING_LEN)
11879 {
11880 probe_rsp_ie_len[counter++] = MAX_CFG_STRING_LEN;
11881 rem_probe_resp_ie_len -= MAX_CFG_STRING_LEN;
11882 }
11883 else
11884 {
11885 probe_rsp_ie_len[counter++] = rem_probe_resp_ie_len;
11886 rem_probe_resp_ie_len = 0;
11887 }
11888 }
11889
11890 rem_probe_resp_ie_len = 0;
11891
11892 if (probe_rsp_ie_len[0] > 0)
11893 {
11894 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11895 WNI_CFG_PROBE_RSP_ADDNIE_DATA1,
11896 (tANI_U8*)(genie - 2),
11897 probe_rsp_ie_len[0], NULL,
11898 eANI_BOOLEAN_FALSE)
11899 == eHAL_STATUS_FAILURE)
11900 {
11901 hddLog(LOGE,
11902 "Could not pass"
11903 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA1 to CCM");
11904 }
11905 rem_probe_resp_ie_len += probe_rsp_ie_len[0];
11906 }
11907
11908 if (probe_rsp_ie_len[1] > 0)
11909 {
11910 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11911 WNI_CFG_PROBE_RSP_ADDNIE_DATA2,
11912 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11913 probe_rsp_ie_len[1], NULL,
11914 eANI_BOOLEAN_FALSE)
11915 == eHAL_STATUS_FAILURE)
11916 {
11917 hddLog(LOGE,
11918 "Could not pass"
11919 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA2 to CCM");
11920 }
11921 rem_probe_resp_ie_len += probe_rsp_ie_len[1];
11922 }
11923
11924 if (probe_rsp_ie_len[2] > 0)
11925 {
11926 if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter),
11927 WNI_CFG_PROBE_RSP_ADDNIE_DATA3,
11928 (tANI_U8*)(genie - (2 + rem_probe_resp_ie_len)),
11929 probe_rsp_ie_len[2], NULL,
11930 eANI_BOOLEAN_FALSE)
11931 == eHAL_STATUS_FAILURE)
11932 {
11933 hddLog(LOGE,
11934 "Could not pass"
11935 "on WNI_CFG_PROBE_RSP_ADDNIE_DATA3 to CCM");
11936 }
11937 rem_probe_resp_ie_len += probe_rsp_ie_len[2];
11938 }
11939
11940 if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter),
11941 WNI_CFG_PROBE_RSP_ADDNIE_FLAG, 1,NULL,
11942 eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE)
11943 {
11944 hddLog(LOGE,
11945 "Could not pass"
11946 "on WNI_CFG_PROBE_RSP_ADDNIE_FLAG to CCM");
11947 }
11948 }
11949 else
11950 {
11951 // Reset WNI_CFG_PROBE_RSP Flags
11952 wlan_hdd_reset_prob_rspies(pAdapter);
11953
11954 hddLog(VOS_TRACE_LEVEL_INFO,
11955 "%s: No Probe Response IE received in set beacon",
11956 __func__);
11957 }
11958 } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */
Jeff Johnson295189b2012-06-20 16:38:30 -070011959 break;
11960 case DOT11F_EID_RSN:
11961 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2);
11962 memset( pWextState->WPARSNIE, 0, MAX_WPA_RSN_IE_LEN );
11963 memcpy( pWextState->WPARSNIE, genie - 2, (eLen + 2)/*ie_len*/);
11964 pWextState->roamProfile.pRSNReqIE = pWextState->WPARSNIE;
11965 pWextState->roamProfile.nRSNReqIELength = eLen + 2; //ie_len;
11966 break;
Abhishek Singh15d95602015-03-24 15:52:57 +053011967
11968 /* Appending Extended Capabilities with Interworking bit set
11969 * in Assoc Req.
11970 *
11971 * In assoc req this EXT Cap will only be taken into account if
11972 * interworkingService bit is set to 1. Currently
11973 * driver is only interested in interworkingService capability
11974 * from supplicant. If in future any other EXT Cap info is
11975 * required from supplicat, it needs to be handled while
11976 * sending Assoc Req in LIM.
11977 */
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011978 case DOT11F_EID_EXTCAP:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011979 {
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011980 v_U16_t curAddIELen = pWextState->assocAddIE.length;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011981 hddLog (VOS_TRACE_LEVEL_INFO, "%s Set Extended CAPS IE(len %d)",
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011982 __func__, eLen + 2);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011983
Ganesh Kondabattini7500fb32015-04-10 14:50:32 +053011984 if( SIR_MAC_MAX_ADD_IE_LENGTH < (pWextState->assocAddIE.length + eLen) )
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011985 {
Jeff Johnson902c9832012-12-10 14:28:09 -080011986 hddLog(VOS_TRACE_LEVEL_FATAL, "Cannot accommodate assocAddIE "
11987 "Need bigger buffer space");
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011988 VOS_ASSERT(0);
11989 return -ENOMEM;
11990 }
11991 memcpy( pWextState->assocAddIE.addIEdata + curAddIELen, genie - 2, eLen + 2);
11992 pWextState->assocAddIE.length += eLen + 2;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053011993
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070011994 pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata;
11995 pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length;
11996 break;
11997 }
Jeff Johnson295189b2012-06-20 16:38:30 -070011998#ifdef FEATURE_WLAN_WAPI
11999 case WLAN_EID_WAPI:
12000 pAdapter->wapi_info.nWapiMode = 1; //Setting WAPI Mode to ON=1
Jeff Johnson0299d0a2013-10-30 12:37:43 -070012001 hddLog(VOS_TRACE_LEVEL_INFO, "WAPI MODE IS %u",
Jeff Johnson295189b2012-06-20 16:38:30 -070012002 pAdapter->wapi_info.nWapiMode);
12003 tmp = (u16 *)ie;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012004 tmp = tmp + 2; // Skip element Id and Len, Version
Jeff Johnson295189b2012-06-20 16:38:30 -070012005 akmsuiteCount = WPA_GET_LE16(tmp);
12006 tmp = tmp + 1;
12007 akmlist = (int *)(tmp);
12008 if(akmsuiteCount <= MAX_NUM_AKM_SUITES)
12009 {
12010 memcpy(akmsuite, akmlist, (4*akmsuiteCount));
12011 }
12012 else
12013 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012014 hddLog(VOS_TRACE_LEVEL_FATAL, "Invalid akmSuite count");
Jeff Johnson295189b2012-06-20 16:38:30 -070012015 VOS_ASSERT(0);
12016 return -EINVAL;
12017 }
12018
12019 if (WAPI_PSK_AKM_SUITE == akmsuite[0])
12020 {
12021 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO PSK",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012022 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012023 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_PSK;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012024 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012025 if (WAPI_CERT_AKM_SUITE == akmsuite[0])
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012026 {
Jeff Johnson295189b2012-06-20 16:38:30 -070012027 hddLog(VOS_TRACE_LEVEL_INFO, "%s: WAPI AUTH MODE SET TO CERTIFICATE",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -070012028 __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012029 pAdapter->wapi_info.wapiAuthMode = WAPI_AUTH_MODE_CERT;
12030 }
12031 break;
12032#endif
12033 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012034 hddLog (VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012035 "%s Set UNKNOWN IE %X", __func__, elementId);
Madan Mohan Koyyalamudief3b66e2012-10-11 14:29:42 -070012036 /* when Unknown IE is received we should break and continue
12037 * to the next IE in the buffer instead we were returning
12038 * so changing this to break */
12039 break;
Jeff Johnson295189b2012-06-20 16:38:30 -070012040 }
12041 genie += eLen;
12042 remLen -= eLen;
12043 }
12044 EXIT();
12045 return 0;
12046}
12047
12048/*
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012049 * FUNCTION: hdd_isWPAIEPresent
12050 * Parse the received IE to find the WPA IE
12051 *
12052 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012053static bool hdd_isWPAIEPresent(
12054#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
12055 const u8 *ie,
12056#else
12057 u8 *ie,
12058#endif
12059 u8 ie_len)
Gopichand Nakkala18f0c262013-05-07 23:25:08 +053012060{
12061 v_U8_t eLen = 0;
12062 v_U16_t remLen = ie_len;
12063 v_U8_t elementId = 0;
12064
12065 while (remLen >= 2)
12066 {
12067 elementId = *ie++;
12068 eLen = *ie++;
12069 remLen -= 2;
12070 if (eLen > remLen)
12071 {
12072 hddLog(VOS_TRACE_LEVEL_ERROR,
12073 "%s: IE length is wrong %d", __func__, eLen);
12074 return FALSE;
12075 }
12076 if ((elementId == DOT11F_EID_WPA) && (remLen > 5))
12077 {
12078 /* OUI - 0x00 0X50 0XF2
12079 WPA Information Element - 0x01
12080 WPA version - 0x01*/
12081 if (0 == memcmp(&ie[0], "\x00\x50\xf2\x01\x01", 5))
12082 return TRUE;
12083 }
12084 ie += eLen;
12085 remLen -= eLen;
12086 }
12087 return FALSE;
12088}
12089
12090/*
Jeff Johnson295189b2012-06-20 16:38:30 -070012091 * FUNCTION: wlan_hdd_cfg80211_set_privacy
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012092 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012093 * parameters during connect operation.
12094 */
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012095int wlan_hdd_cfg80211_set_privacy(hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012096 struct cfg80211_connect_params *req
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012097 )
Jeff Johnson295189b2012-06-20 16:38:30 -070012098{
12099 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012100 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012101 ENTER();
12102
12103 /*set wpa version*/
12104 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
12105
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012106 if (req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012107 {
Gopichand Nakkala781ded42013-06-28 12:10:45 +053012108 if (NL80211_WPA_VERSION_1 == req->crypto.wpa_versions)
Jeff Johnson295189b2012-06-20 16:38:30 -070012109 {
12110 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12111 }
12112 else if (NL80211_WPA_VERSION_2 == req->crypto.wpa_versions)
12113 {
12114 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12115 }
12116 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012117
12118 hddLog(VOS_TRACE_LEVEL_INFO, "%s: set wpa version to %d", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070012119 pWextState->wpaVersion);
12120
12121 /*set authentication type*/
12122 status = wlan_hdd_cfg80211_set_auth_type(pAdapter, req->auth_type);
12123
12124 if (0 > status)
12125 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012126 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012127 "%s: failed to set authentication type ", __func__);
12128 return status;
12129 }
12130
12131 /*set key mgmt type*/
12132 if (req->crypto.n_akm_suites)
12133 {
12134 status = wlan_hdd_set_akm_suite(pAdapter, req->crypto.akm_suites[0]);
12135 if (0 > status)
12136 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012137 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set akm suite",
Jeff Johnson295189b2012-06-20 16:38:30 -070012138 __func__);
12139 return status;
12140 }
12141 }
12142
12143 /*set pairwise cipher type*/
12144 if (req->crypto.n_ciphers_pairwise)
12145 {
12146 status = wlan_hdd_cfg80211_set_cipher(pAdapter,
12147 req->crypto.ciphers_pairwise[0], true);
12148 if (0 > status)
12149 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012150 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012151 "%s: failed to set unicast cipher type", __func__);
12152 return status;
12153 }
12154 }
12155 else
12156 {
12157 /*Reset previous cipher suite to none*/
12158 status = wlan_hdd_cfg80211_set_cipher(pAdapter, 0, true);
12159 if (0 > status)
12160 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012161 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012162 "%s: failed to set unicast cipher type", __func__);
12163 return status;
12164 }
12165 }
12166
12167 /*set group cipher type*/
12168 status = wlan_hdd_cfg80211_set_cipher(pAdapter, req->crypto.cipher_group,
12169 false);
12170
12171 if (0 > status)
12172 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012173 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set mcast cipher type",
Jeff Johnson295189b2012-06-20 16:38:30 -070012174 __func__);
12175 return status;
12176 }
12177
Chet Lanctot186b5732013-03-18 10:26:30 -070012178#ifdef WLAN_FEATURE_11W
12179 pWextState->roamProfile.MFPEnabled = (req->mfp == NL80211_MFP_REQUIRED);
12180#endif
12181
Jeff Johnson295189b2012-06-20 16:38:30 -070012182 /*parse WPA/RSN IE, and set the correspoing fileds in Roam profile*/
12183 if (req->ie_len)
12184 {
12185 status = wlan_hdd_cfg80211_set_ie(pAdapter, req->ie, req->ie_len);
12186 if ( 0 > status)
12187 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012188 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse the WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012189 __func__);
12190 return status;
12191 }
12192 }
12193
12194 /*incase of WEP set default key information*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012195 if (req->key && req->key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012196 {
12197 if ( (WLAN_CIPHER_SUITE_WEP40 == req->crypto.ciphers_pairwise[0])
12198 || (WLAN_CIPHER_SUITE_WEP104 == req->crypto.ciphers_pairwise[0])
12199 )
12200 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012201 if ( IW_AUTH_KEY_MGMT_802_1X
Jeff Johnson295189b2012-06-20 16:38:30 -070012202 == (pWextState->authKeyMgmt & IW_AUTH_KEY_MGMT_802_1X ))
12203 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012204 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Dynamic WEP not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070012205 __func__);
12206 return -EOPNOTSUPP;
12207 }
12208 else
12209 {
12210 u8 key_len = req->key_len;
12211 u8 key_idx = req->key_idx;
12212
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012213 if ((eCSR_SECURITY_WEP_KEYSIZE_MAX_BYTES >= key_len)
Jeff Johnson295189b2012-06-20 16:38:30 -070012214 && (CSR_MAX_NUM_KEY > key_idx)
12215 )
12216 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012217 hddLog(VOS_TRACE_LEVEL_INFO,
12218 "%s: setting default wep key, key_idx = %hu key_len %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070012219 __func__, key_idx, key_len);
12220 vos_mem_copy(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012221 &pWextState->roamProfile.Keys.KeyMaterial[key_idx][0],
Jeff Johnson295189b2012-06-20 16:38:30 -070012222 req->key, key_len);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012223 pWextState->roamProfile.Keys.KeyLength[key_idx] =
Jeff Johnson295189b2012-06-20 16:38:30 -070012224 (u8)key_len;
12225 pWextState->roamProfile.Keys.defaultIndex = (u8)key_idx;
12226 }
12227 }
12228 }
12229 }
12230
12231 return status;
12232}
12233
12234/*
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012235 * FUNCTION: wlan_hdd_try_disconnect
12236 * This function is used to disconnect from previous
12237 * connection
12238 */
12239static int wlan_hdd_try_disconnect( hdd_adapter_t *pAdapter )
12240{
12241 long ret = 0;
12242 hdd_station_ctx_t *pHddStaCtx;
12243 eMib_dot11DesiredBssType connectedBssType;
12244
12245 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12246
12247 hdd_connGetConnectedBssType(pHddStaCtx,&connectedBssType );
12248
12249 if((eMib_dot11DesiredBssType_independent == connectedBssType) ||
12250 (eConnectionState_Associated == pHddStaCtx->conn_info.connState) ||
12251 (eConnectionState_IbssConnected == pHddStaCtx->conn_info.connState))
12252 {
12253 /* Issue disconnect to CSR */
12254 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12255 if( eHAL_STATUS_SUCCESS ==
12256 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12257 pAdapter->sessionId,
12258 eCSR_DISCONNECT_REASON_UNSPECIFIED ) )
12259 {
12260 ret = wait_for_completion_interruptible_timeout(
12261 &pAdapter->disconnect_comp_var,
12262 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12263 if (0 >= ret)
12264 {
12265 hddLog(LOGE, FL("Failed to receive disconnect event"));
12266 return -EALREADY;
12267 }
12268 }
12269 }
12270 else if(eConnectionState_Disconnecting == pHddStaCtx->conn_info.connState)
12271 {
12272 ret = wait_for_completion_interruptible_timeout(
12273 &pAdapter->disconnect_comp_var,
12274 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
12275 if (0 >= ret)
12276 {
12277 hddLog(LOGE, FL("Failed to receive disconnect event"));
12278 return -EALREADY;
12279 }
12280 }
12281
12282 return 0;
12283}
12284
12285/*
Agarwal Ashish51325b52014-06-16 16:50:49 +053012286 * FUNCTION: __wlan_hdd_cfg80211_connect
12287 * This function is used to start the association process
Jeff Johnson295189b2012-06-20 16:38:30 -070012288 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012289static int __wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012290 struct net_device *ndev,
12291 struct cfg80211_connect_params *req
12292 )
12293{
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012294 int status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012295 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( ndev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012296 VOS_STATUS exitbmpsStatus = VOS_STATUS_E_INVAL;
Sushant Kaushikba6764e2014-06-30 19:52:09 +053012297 hdd_context_t *pHddCtx = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070012298
12299 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012300
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012301 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12302 TRACE_CODE_HDD_CFG80211_CONNECT,
12303 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012304 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012305 "%s: device_mode = %s (%d)", __func__,
12306 hdd_device_modetoString(pAdapter->device_mode),
12307 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012308
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012309 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012310 if (!pHddCtx)
12311 {
12312 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
12313 "%s: HDD context is null", __func__);
Agarwal Ashish51325b52014-06-16 16:50:49 +053012314 return -EINVAL;
Rajesh Chauhana0516c62014-01-30 16:11:18 -080012315 }
12316
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012317 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012318 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012319 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012320 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012321 }
12322
Agarwal Ashish51325b52014-06-16 16:50:49 +053012323 if (vos_max_concurrent_connections_reached()) {
12324 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12325 return -ECONNREFUSED;
12326 }
12327
Jeff Johnson295189b2012-06-20 16:38:30 -070012328#ifdef WLAN_BTAMP_FEATURE
12329 //Infra connect not supported when AMP traffic is on.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012330 if( VOS_TRUE == WLANBAP_AmpSessionOn() )
Jeff Johnson295189b2012-06-20 16:38:30 -070012331 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012332 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070012333 "%s: No connection when AMP is on", __func__);
Madan Mohan Koyyalamudicae253a2012-11-06 19:10:35 -080012334 return -ECONNREFUSED;
Jeff Johnson295189b2012-06-20 16:38:30 -070012335 }
12336#endif
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012337
12338 //If Device Mode is Station Concurrent Sessions Exit BMps
12339 //P2P Mode will be taken care in Open/close adapter
12340 if((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) &&
Agarwal Ashish51325b52014-06-16 16:50:49 +053012341 (vos_concurrent_open_sessions_running())) {
12342 exitbmpsStatus = hdd_disable_bmps_imps(pHddCtx,
12343 WLAN_HDD_INFRA_STATION);
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012344 }
12345
12346 /*Try disconnecting if already in connected state*/
12347 status = wlan_hdd_try_disconnect(pAdapter);
12348 if ( 0 > status)
12349 {
12350 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12351 " connection"));
12352 return -EALREADY;
12353 }
12354
Jeff Johnson295189b2012-06-20 16:38:30 -070012355 /*initialise security parameters*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012356 status = wlan_hdd_cfg80211_set_privacy(pAdapter, req);
Jeff Johnson295189b2012-06-20 16:38:30 -070012357
12358 if ( 0 > status)
12359 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012360 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security params",
Jeff Johnson295189b2012-06-20 16:38:30 -070012361 __func__);
12362 return status;
12363 }
Mohit Khanna765234a2012-09-11 15:08:35 -070012364 if ( req->channel )
12365 {
12366 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
12367 req->ssid_len, req->bssid,
12368 req->channel->hw_value);
12369 }
12370 else
12371 {
12372 status = wlan_hdd_cfg80211_connect_start(pAdapter, req->ssid,
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012373 req->ssid_len, req->bssid, 0);
Mohit Khanna765234a2012-09-11 15:08:35 -070012374 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012375
Sushant Kaushikd7083982015-03-18 14:33:24 +053012376 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012377 {
12378 //ReEnable BMPS if disabled
12379 if((VOS_STATUS_SUCCESS == exitbmpsStatus) &&
12380 (NULL != pHddCtx))
12381 {
Gopichand Nakkalaa2fe5b02013-06-06 16:32:28 +053012382 if (pHddCtx->hdd_wlan_suspended)
12383 {
12384 hdd_set_pwrparams(pHddCtx);
12385 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012386 //ReEnable Bmps and Imps back
12387 hdd_enable_bmps_imps(pHddCtx);
12388 }
Agarwal Ashish51325b52014-06-16 16:50:49 +053012389 hddLog(VOS_TRACE_LEVEL_ERROR, FL("connect failed"));
Jeff Johnson295189b2012-06-20 16:38:30 -070012390 return status;
12391 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012392 pHddCtx->isAmpAllowed = VOS_FALSE;
Jeff Johnson295189b2012-06-20 16:38:30 -070012393 EXIT();
12394 return status;
12395}
12396
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012397static int wlan_hdd_cfg80211_connect( struct wiphy *wiphy,
12398 struct net_device *ndev,
12399 struct cfg80211_connect_params *req)
12400{
12401 int ret;
12402 vos_ssr_protect(__func__);
12403 ret = __wlan_hdd_cfg80211_connect(wiphy, ndev, req);
12404 vos_ssr_unprotect(__func__);
12405
12406 return ret;
12407}
Jeff Johnson295189b2012-06-20 16:38:30 -070012408
12409/*
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012410 * FUNCTION: wlan_hdd_disconnect
12411 * This function is used to issue a disconnect request to SME
12412 */
12413int wlan_hdd_disconnect( hdd_adapter_t *pAdapter, u16 reason )
12414{
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012415 int status, result = 0;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012416 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012417 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012418 long ret;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012419
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012420 ENTER();
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012421
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012422 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012423 if (0 != status)
12424 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012425 return status;
12426 }
12427
Sushant Kaushikb4834d22015-07-15 15:29:05 +053012428 if (pHddStaCtx->conn_info.connState == eConnectionState_Connecting)
12429 {
12430 sme_abortConnection(WLAN_HDD_GET_HAL_CTX(pAdapter),
12431 pAdapter->sessionId);
12432 }
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012433 pHddCtx->isAmpAllowed = VOS_TRUE;
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012434
Agarwal Ashish47d18112014-08-04 19:55:07 +053012435 /* Need to apply spin lock before decreasing active sessions
12436 * as there can be chance for double decrement if context switch
12437 * Calls hdd_DisConnectHandler.
12438 */
12439
12440 spin_lock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012441 if (eConnectionState_Associated == pHddStaCtx->conn_info.connState)
12442 {
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012443 wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode);
12444 }
Agarwal Ashish47d18112014-08-04 19:55:07 +053012445 hdd_connSetConnectionState( pHddStaCtx, eConnectionState_Disconnecting );
12446 spin_unlock_bh(&pAdapter->lock_for_active_session);
Agarwal Ashishc65b5ca2014-07-28 21:02:57 +053012447
Abhishek Singhf4669da2014-05-26 15:07:49 +053012448 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Agarwal Ashish47d18112014-08-04 19:55:07 +053012449 FL( "Set HDD connState to eConnectionState_Disconnecting" ));
12450
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012451 INIT_COMPLETION(pAdapter->disconnect_comp_var);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012452
Mihir Shete182a0b22014-08-18 16:08:48 +053012453 /*
12454 * stop tx queues before deleting STA/BSS context from the firmware.
12455 * tx has to be disabled because the firmware can get busy dropping
12456 * the tx frames after BSS/STA has been deleted and will not send
12457 * back a response resulting in WDI timeout
12458 */
Padma, Santhosh Kumar9dacb5c2014-12-17 19:22:56 +053012459 hddLog(VOS_TRACE_LEVEL_INFO, FL("Disabling queues"));
Mihir Shete182a0b22014-08-18 16:08:48 +053012460 netif_tx_disable(pAdapter->dev);
12461 netif_carrier_off(pAdapter->dev);
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012462
Mihir Shete182a0b22014-08-18 16:08:48 +053012463 /*issue disconnect*/
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012464 status = sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter),
12465 pAdapter->sessionId, reason);
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012466 if(eHAL_STATUS_CMD_NOT_QUEUED == status)
12467 {
12468 hddLog(VOS_TRACE_LEVEL_INFO,
12469 FL("status = %d, already disconnected"),
12470 (int)status );
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012471
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012472 }
12473 else if ( 0 != status )
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012474 {
12475 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012476 "%s csrRoamDisconnect failure, returned %d",
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012477 __func__, (int)status );
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012478 result = -EINVAL;
12479 goto disconnected;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012480 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012481 ret = wait_for_completion_interruptible_timeout(
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012482 &pAdapter->disconnect_comp_var,
12483 msecs_to_jiffies(WLAN_WAIT_TIME_DISCONNECT));
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012484 if (!ret && ( eHAL_STATUS_CMD_NOT_QUEUED != status ))
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012485 {
12486 hddLog(VOS_TRACE_LEVEL_ERROR,
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012487 "%s: Failed to disconnect, timed out", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012488 result = -ETIMEDOUT;
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012489 }
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012490 else if (ret == -ERESTARTSYS)
Mahesh A Saptasagar05a357e2014-02-26 16:28:06 +053012491 {
12492 hddLog(VOS_TRACE_LEVEL_ERROR,
12493 "%s: Failed to disconnect, wait interrupted", __func__);
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012494 result = -ERESTARTSYS;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053012495 }
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012496disconnected:
Abhishek Singhdc2bfd42014-06-19 17:59:05 +053012497 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
12498 FL("Set HDD connState to eConnectionState_NotConnected"));
12499 pHddStaCtx->conn_info.connState = eConnectionState_NotConnected;
12500
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012501 EXIT();
Abhishek Singh6ab864d2014-11-27 12:10:10 +053012502 return result;
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012503}
12504
12505
12506/*
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012507 * FUNCTION: __wlan_hdd_cfg80211_disconnect
Jeff Johnson295189b2012-06-20 16:38:30 -070012508 * This function is used to issue a disconnect request to SME
12509 */
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012510static int __wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012511 struct net_device *dev,
12512 u16 reason
12513 )
12514{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012515 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012516 int status;
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012517 tCsrRoamProfile *pRoamProfile;
12518 hdd_station_ctx_t *pHddStaCtx;
12519 hdd_context_t *pHddCtx;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012520#ifdef FEATURE_WLAN_TDLS
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012521 tANI_U8 staIdx;
12522#endif
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012523
Jeff Johnson295189b2012-06-20 16:38:30 -070012524 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012525
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053012526 if (!pAdapter) {
12527 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
12528 return -EINVAL;
12529 }
12530
12531 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12532 if (!pHddStaCtx) {
12533 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD STA context is NULL"));
12534 return -EINVAL;
12535 }
12536
12537 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
12538 status = wlan_hdd_validate_context(pHddCtx);
12539 if (0 != status)
12540 {
12541 return status;
12542 }
12543
12544 pRoamProfile = &(WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter))->roamProfile;
12545
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012546 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12547 TRACE_CODE_HDD_CFG80211_DISCONNECT,
12548 pAdapter->sessionId, reason));
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012549 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s(%d)",
12550 __func__, hdd_device_modetoString(pAdapter->device_mode),
12551 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012552
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012553 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Disconnect called with reason code %d",
12554 __func__, reason);
Jeff Johnson295189b2012-06-20 16:38:30 -070012555
Jeff Johnson295189b2012-06-20 16:38:30 -070012556 if (NULL != pRoamProfile)
12557 {
12558 /*issue disconnect request to SME, if station is in connected state*/
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012559 if ((pHddStaCtx->conn_info.connState == eConnectionState_Associated) ||
12560 (pHddStaCtx->conn_info.connState == eConnectionState_Connecting))
Jeff Johnson295189b2012-06-20 16:38:30 -070012561 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012562 eCsrRoamDisconnectReason reasonCode =
Jeff Johnson295189b2012-06-20 16:38:30 -070012563 eCSR_DISCONNECT_REASON_UNSPECIFIED;
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012564 hdd_scaninfo_t *pScanInfo;
Jeff Johnson295189b2012-06-20 16:38:30 -070012565 switch(reason)
12566 {
12567 case WLAN_REASON_MIC_FAILURE:
12568 reasonCode = eCSR_DISCONNECT_REASON_MIC_ERROR;
12569 break;
12570
12571 case WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY:
12572 case WLAN_REASON_DISASSOC_AP_BUSY:
12573 case WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA:
12574 reasonCode = eCSR_DISCONNECT_REASON_DISASSOC;
12575 break;
12576
12577 case WLAN_REASON_PREV_AUTH_NOT_VALID:
12578 case WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA:
Abhishek Singhc3269a52014-05-21 17:22:24 +053012579 case WLAN_REASON_DEAUTH_LEAVING:
Jeff Johnson295189b2012-06-20 16:38:30 -070012580 reasonCode = eCSR_DISCONNECT_REASON_DEAUTH;
12581 break;
12582
Jeff Johnson295189b2012-06-20 16:38:30 -070012583 default:
12584 reasonCode = eCSR_DISCONNECT_REASON_UNSPECIFIED;
12585 break;
12586 }
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012587 pScanInfo = &pHddCtx->scan_info;
12588 if (pScanInfo->mScanPending)
12589 {
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012590 hddLog(VOS_TRACE_LEVEL_INFO, "Disconnect is in progress, "
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012591 "Aborting Scan");
Kaushik, Sushant4975a572014-10-21 16:07:48 +053012592 hdd_abort_mac_scan(pHddCtx, pScanInfo->sessionId,
Srinivas, Dasari138af4f2014-02-07 11:13:45 +053012593 eCSR_SCAN_ABORT_DEFAULT);
Gopichand Nakkalaaa353782013-05-17 20:36:22 +053012594 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012595
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012596#ifdef FEATURE_WLAN_TDLS
12597 /* First clean up the tdls peers if any */
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012598 for (staIdx = 0 ; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++)
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012599 {
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012600 if ((pHddCtx->tdlsConnInfo[staIdx].sessionId == pAdapter->sessionId) &&
12601 (pHddCtx->tdlsConnInfo[staIdx].staId))
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012602 {
Hoonki Lee11f7dda2013-02-14 16:55:44 -080012603 uint8 *mac;
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012604 mac = pHddCtx->tdlsConnInfo[staIdx].peerMac.bytes;
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053012605 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012606 "%s: call sme_DeleteTdlsPeerSta staId %d sessionId %d " MAC_ADDRESS_STR,
Gopichand Nakkala4327a152013-03-04 23:22:42 -080012607 __func__, pHddCtx->tdlsConnInfo[staIdx].staId, pAdapter->sessionId,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070012608 MAC_ADDR_ARRAY(mac));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053012609 status = sme_DeleteTdlsPeerSta(
12610 WLAN_HDD_GET_HAL_CTX(pAdapter),
12611 pAdapter->sessionId,
12612 mac);
12613 if (status != eHAL_STATUS_SUCCESS) {
12614 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
12615 return -EPERM;
12616 }
Gopichand Nakkala2a0a1572013-02-10 21:39:16 -080012617 }
12618 }
12619#endif
Arun Kumar Khandavalli94a2bb02013-12-28 19:17:25 +053012620 hddLog(LOG1, FL("Disconnecting with reasoncode:%u"), reasonCode);
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012621 status = wlan_hdd_disconnect(pAdapter, reasonCode);
12622 if ( 0 != status )
Jeff Johnson295189b2012-06-20 16:38:30 -070012623 {
12624 hddLog(VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012625 "%s wlan_hdd_disconnect failure, returned %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012626 __func__, (int)status );
12627 return -EINVAL;
12628 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012629 }
Mahesh A Saptasagar280fd5a2013-12-05 15:38:31 +053012630 else
12631 {
12632 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: unexpected cfg disconnect API"
12633 "called while in %d state", __func__,
12634 pHddStaCtx->conn_info.connState);
12635 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012636 }
12637 else
12638 {
12639 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid roam profile", __func__);
12640 }
12641
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012642 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012643 return status;
12644}
12645
Mahesh A Saptasagarfafb7fe2014-05-16 13:19:37 +053012646static int wlan_hdd_cfg80211_disconnect( struct wiphy *wiphy,
12647 struct net_device *dev,
12648 u16 reason
12649 )
12650{
12651 int ret;
12652 vos_ssr_protect(__func__);
12653 ret = __wlan_hdd_cfg80211_disconnect(wiphy, dev, reason);
12654 vos_ssr_unprotect(__func__);
12655
12656 return ret;
12657}
Gopichand Nakkala78a6c812013-05-13 16:39:49 +053012658
Jeff Johnson295189b2012-06-20 16:38:30 -070012659/*
12660 * FUNCTION: wlan_hdd_cfg80211_set_privacy_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012661 * This function is used to initialize the security
Jeff Johnson295189b2012-06-20 16:38:30 -070012662 * settings in IBSS mode.
12663 */
12664static int wlan_hdd_cfg80211_set_privacy_ibss(
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012665 hdd_adapter_t *pAdapter,
Jeff Johnson295189b2012-06-20 16:38:30 -070012666 struct cfg80211_ibss_params *params
12667 )
12668{
12669 int status = 0;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012670 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
Jeff Johnson295189b2012-06-20 16:38:30 -070012671 eCsrEncryptionType encryptionType = eCSR_ENCRYPT_TYPE_NONE;
12672 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012673
Jeff Johnson295189b2012-06-20 16:38:30 -070012674 ENTER();
12675
12676 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_DISABLED;
Ravi Joshib58ca0d2013-10-29 09:50:23 -070012677 vos_mem_zero(&pHddStaCtx->ibss_enc_key, sizeof(tCsrRoamSetKey));
Jeff Johnson295189b2012-06-20 16:38:30 -070012678
12679 if (params->ie_len && ( NULL != params->ie) )
12680 {
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012681 if (wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12682 params->ie_len, WLAN_EID_RSN ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012683 {
12684 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA2;
12685 encryptionType = eCSR_ENCRYPT_TYPE_AES;
12686 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012687 else if ( hdd_isWPAIEPresent (params->ie, params->ie_len ))
Jeff Johnson295189b2012-06-20 16:38:30 -070012688 {
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012689 tDot11fIEWPA dot11WPAIE;
12690 tHalHandle halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012691 u8 *ie;
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012692
Wilson Yang00256342013-10-10 23:13:38 -070012693 memset(&dot11WPAIE, 0, sizeof(dot11WPAIE));
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012694 ie = wlan_hdd_cfg80211_get_ie_ptr (params->ie,
12695 params->ie_len, DOT11F_EID_WPA);
12696 if ( NULL != ie )
12697 {
12698 pWextState->wpaVersion = IW_AUTH_WPA_VERSION_WPA;
12699 // Unpack the WPA IE
12700 //Skip past the EID byte and length byte - and four byte WiFi OUI
12701 dot11fUnpackIeWPA((tpAniSirGlobal) halHandle,
12702 &ie[2+4],
12703 ie[1] - 4,
12704 &dot11WPAIE);
12705 /*Extract the multicast cipher, the encType for unicast
12706 cipher for wpa-none is none*/
12707 encryptionType =
12708 hdd_TranslateWPAToCsrEncryptionType(dot11WPAIE.multicast_cipher);
12709 }
Jeff Johnson295189b2012-06-20 16:38:30 -070012710 }
Shailender Karmuchi67edd312013-06-18 16:30:48 -070012711
Jeff Johnson295189b2012-06-20 16:38:30 -070012712 status = wlan_hdd_cfg80211_set_ie(pAdapter, params->ie, params->ie_len);
12713
12714 if (0 > status)
12715 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012716 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to parse WPA/RSN IE",
Jeff Johnson295189b2012-06-20 16:38:30 -070012717 __func__);
12718 return status;
12719 }
12720 }
12721
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012722 pWextState->roamProfile.AuthType.authType[0] =
12723 pHddStaCtx->conn_info.authType =
Jeff Johnson295189b2012-06-20 16:38:30 -070012724 eCSR_AUTH_TYPE_OPEN_SYSTEM;
12725
12726 if (params->privacy)
12727 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012728 /* Security enabled IBSS, At this time there is no information available
12729 * about the security paramters, so initialise the encryption type to
Jeff Johnson295189b2012-06-20 16:38:30 -070012730 * eCSR_ENCRYPT_TYPE_WEP40_STATICKEY.
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012731 * The correct security parameters will be updated later in
Jeff Johnson295189b2012-06-20 16:38:30 -070012732 * wlan_hdd_cfg80211_add_key */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012733 /* Hal expects encryption type to be set inorder
Jeff Johnson295189b2012-06-20 16:38:30 -070012734 *enable privacy bit in beacons */
12735
12736 encryptionType = eCSR_ENCRYPT_TYPE_WEP40_STATICKEY;
12737 }
Shailender Karmuchi642e9812013-05-30 14:34:49 -070012738 VOS_TRACE (VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
12739 "encryptionType=%d", encryptionType);
Jeff Johnson295189b2012-06-20 16:38:30 -070012740 pHddStaCtx->conn_info.ucEncryptionType = encryptionType;
12741 pWextState->roamProfile.EncryptionType.numEntries = 1;
12742 pWextState->roamProfile.EncryptionType.encryptionType[0] = encryptionType;
Jeff Johnson295189b2012-06-20 16:38:30 -070012743 return status;
12744}
12745
12746/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012747 * FUNCTION: __wlan_hdd_cfg80211_join_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012748 * This function is used to create/join an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012749 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012750static int __wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012751 struct net_device *dev,
12752 struct cfg80211_ibss_params *params
12753 )
12754{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012755 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Jeff Johnson295189b2012-06-20 16:38:30 -070012756 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12757 tCsrRoamProfile *pRoamProfile;
12758 int status;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012759 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
12760 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012761 tSirMacAddr bssid;
Jeff Johnson295189b2012-06-20 16:38:30 -070012762
12763 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012764
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012765 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12766 TRACE_CODE_HDD_CFG80211_JOIN_IBSS,
12767 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012768 hddLog(VOS_TRACE_LEVEL_INFO,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012769 "%s: device_mode = %s (%d)", __func__,
12770 hdd_device_modetoString(pAdapter->device_mode),
12771 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012772
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012773 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012774 if (0 != status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012775 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012776 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012777 }
12778
12779 if (NULL == pWextState)
12780 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012781 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012782 __func__);
12783 return -EIO;
12784 }
12785
Agarwal Ashish51325b52014-06-16 16:50:49 +053012786 if (vos_max_concurrent_connections_reached()) {
12787 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
12788 return -ECONNREFUSED;
12789 }
12790
Vinay Krishna Eranna21042322014-01-08 19:21:39 +053012791 /*Try disconnecting if already in connected state*/
12792 status = wlan_hdd_try_disconnect(pAdapter);
12793 if ( 0 > status)
12794 {
12795 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to disconnect the existing"
12796 " IBSS connection"));
12797 return -EALREADY;
12798 }
12799
Jeff Johnson295189b2012-06-20 16:38:30 -070012800 pRoamProfile = &pWextState->roamProfile;
12801
12802 if ( eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType )
12803 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012804 hddLog (VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080012805 "%s Interface type is not set to IBSS", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012806 return -EINVAL;
12807 }
12808
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012809 /* BSSID is provided by upper layers hence no need to AUTO generate */
12810 if (NULL != params->bssid) {
12811 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12812 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) {
12813 hddLog (VOS_TRACE_LEVEL_ERROR,
12814 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12815 return -EIO;
12816 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012817 vos_mem_copy((v_U8_t *)bssid, (v_U8_t *)params->bssid, sizeof(bssid));
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012818 }
krunal sonie9002db2013-11-25 14:24:17 -080012819 else if(pHddCtx->cfg_ini->isCoalesingInIBSSAllowed == 0)
12820 {
12821 if (ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_IBSS_AUTO_BSSID, 0,
12822 NULL, eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE)
12823 {
12824 hddLog (VOS_TRACE_LEVEL_ERROR,
12825 "%s:ccmCfgStInt faild for WNI_CFG_IBSS_AUTO_BSSID", __func__);
12826 return -EIO;
12827 }
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012828
12829 vos_mem_copy((v_U8_t *)bssid,
krunal sonie9002db2013-11-25 14:24:17 -080012830 (v_U8_t *)&pHddCtx->cfg_ini->IbssBssid.bytes[0],
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012831 sizeof(bssid));
krunal sonie9002db2013-11-25 14:24:17 -080012832 }
Praveen Kumar Sirisillad123d142013-09-24 16:50:13 -070012833
Jeff Johnson295189b2012-06-20 16:38:30 -070012834 /* Set Channel */
Yue Maf49ba872013-08-19 12:04:25 -070012835 if (NULL !=
12836#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12837 params->chandef.chan)
12838#else
12839 params->channel)
12840#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070012841 {
12842 u8 channelNum;
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012843 v_U32_t numChans = WNI_CFG_VALID_CHANNEL_LIST_LEN;
12844 v_U8_t validChan[WNI_CFG_VALID_CHANNEL_LIST_LEN];
12845 tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
12846 int indx;
Jeff Johnson295189b2012-06-20 16:38:30 -070012847
12848 /* Get channel number */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012849 channelNum =
Yue Maf49ba872013-08-19 12:04:25 -070012850 ieee80211_frequency_to_channel(
12851#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
12852 params->chandef.chan->center_freq);
12853#else
12854 params->channel->center_freq);
12855#endif
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012856
12857 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
12858 validChan, &numChans))
Jeff Johnson295189b2012-06-20 16:38:30 -070012859 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012860 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: No valid channel list",
12861 __func__);
12862 return -EOPNOTSUPP;
Jeff Johnson295189b2012-06-20 16:38:30 -070012863 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012864
12865 for (indx = 0; indx < numChans; indx++)
Jeff Johnson295189b2012-06-20 16:38:30 -070012866 {
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012867 if (channelNum == validChan[indx])
12868 {
12869 break;
12870 }
12871 }
12872 if (indx >= numChans)
12873 {
12874 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Not valid Channel %d",
Jeff Johnson295189b2012-06-20 16:38:30 -070012875 __func__, channelNum);
12876 return -EINVAL;
12877 }
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012878 /* Set the Operational Channel */
12879 hddLog(VOS_TRACE_LEVEL_INFO_HIGH, "%s: set channel %d", __func__,
12880 channelNum);
12881 pRoamProfile->ChannelInfo.numOfChannels = 1;
12882 pHddStaCtx->conn_info.operationChannel = channelNum;
12883 pRoamProfile->ChannelInfo.ChannelList =
12884 &pHddStaCtx->conn_info.operationChannel;
Jeff Johnson295189b2012-06-20 16:38:30 -070012885 }
12886
12887 /* Initialize security parameters */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012888 status = wlan_hdd_cfg80211_set_privacy_ibss(pAdapter, params);
Jeff Johnson295189b2012-06-20 16:38:30 -070012889 if (status < 0)
12890 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012891 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: failed to set security parameters",
Jeff Johnson295189b2012-06-20 16:38:30 -070012892 __func__);
12893 return status;
12894 }
12895
12896 /* Issue connect start */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012897 status = wlan_hdd_cfg80211_connect_start(pAdapter, params->ssid,
Shailender Karmuchi15cd0672013-05-15 19:50:04 -070012898 params->ssid_len, params->bssid,
12899 pHddStaCtx->conn_info.operationChannel);
Jeff Johnson295189b2012-06-20 16:38:30 -070012900
12901 if (0 > status)
Jeff Johnson295189b2012-06-20 16:38:30 -070012902 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: connect failed", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070012903
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012904 EXIT();
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053012905 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012906}
12907
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012908static int wlan_hdd_cfg80211_join_ibss( struct wiphy *wiphy,
12909 struct net_device *dev,
12910 struct cfg80211_ibss_params *params
12911 )
12912{
12913 int ret = 0;
12914
12915 vos_ssr_protect(__func__);
12916 ret = __wlan_hdd_cfg80211_join_ibss(wiphy, dev, params);
12917 vos_ssr_unprotect(__func__);
12918
12919 return ret;
12920}
12921
Jeff Johnson295189b2012-06-20 16:38:30 -070012922/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012923 * FUNCTION: __wlan_hdd_cfg80211_leave_ibss
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012924 * This function is used to leave an IBSS
Jeff Johnson295189b2012-06-20 16:38:30 -070012925 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012926static int __wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012927 struct net_device *dev
12928 )
12929{
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012930 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012931 hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter);
12932 tCsrRoamProfile *pRoamProfile;
12933 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012934 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070012935
12936 ENTER();
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053012937
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053012938 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
12939 TRACE_CODE_HDD_CFG80211_LEAVE_IBSS,
12940 pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012941 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012942 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012943 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012944 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070012945 }
12946
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053012947 hddLog(VOS_TRACE_LEVEL_INFO, "%s: device_mode = %s (%d)", __func__,
12948 hdd_device_modetoString(pAdapter->device_mode),
12949 pAdapter->device_mode);
Jeff Johnson295189b2012-06-20 16:38:30 -070012950 if (NULL == pWextState)
12951 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080012952 hddLog (VOS_TRACE_LEVEL_ERROR, "%s ERROR: Data Storage Corruption",
Jeff Johnson295189b2012-06-20 16:38:30 -070012953 __func__);
12954 return -EIO;
12955 }
12956
12957 pRoamProfile = &pWextState->roamProfile;
12958
12959 /* Issue disconnect only if interface type is set to IBSS */
12960 if (eCSR_BSS_TYPE_START_IBSS != pRoamProfile->BSSType)
12961 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053012962 hddLog (VOS_TRACE_LEVEL_ERROR, "%s: BSS Type is not set to IBSS",
Jeff Johnson295189b2012-06-20 16:38:30 -070012963 __func__);
12964 return -EINVAL;
12965 }
12966
12967 /* Issue Disconnect request */
12968 INIT_COMPLETION(pAdapter->disconnect_comp_var);
12969 sme_RoamDisconnect( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
12970 eCSR_DISCONNECT_REASON_IBSS_LEAVE);
12971
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053012972 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070012973 return 0;
12974}
12975
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053012976static int wlan_hdd_cfg80211_leave_ibss( struct wiphy *wiphy,
12977 struct net_device *dev
12978 )
12979{
12980 int ret = 0;
12981
12982 vos_ssr_protect(__func__);
12983 ret = __wlan_hdd_cfg80211_leave_ibss(wiphy, dev);
12984 vos_ssr_unprotect(__func__);
12985
12986 return ret;
12987}
12988
Jeff Johnson295189b2012-06-20 16:38:30 -070012989/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012990 * FUNCTION: __wlan_hdd_cfg80211_set_wiphy_params
Jeff Johnson295189b2012-06-20 16:38:30 -070012991 * This function is used to set the phy parameters
12992 * (RTS Threshold/FRAG Threshold/Retry Count etc ...)
12993 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053012994static int __wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
Jeff Johnson295189b2012-06-20 16:38:30 -070012995 u32 changed)
12996{
12997 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
12998 tHalHandle hHal = pHddCtx->hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053012999 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013000
13001 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013002
13003 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013004 TRACE_CODE_HDD_CFG80211_SET_WIPHY_PARAMS,
13005 NO_SESSION, wiphy->rts_threshold));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013006
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013007 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013008 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013009 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013010 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013011 }
13012
Jeff Johnson295189b2012-06-20 16:38:30 -070013013 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
13014 {
13015 u16 rts_threshold = (wiphy->rts_threshold == -1) ?
13016 WNI_CFG_RTS_THRESHOLD_STAMAX :
13017 wiphy->rts_threshold;
13018
13019 if ((WNI_CFG_RTS_THRESHOLD_STAMIN > rts_threshold) ||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013020 (WNI_CFG_RTS_THRESHOLD_STAMAX < rts_threshold))
Jeff Johnson295189b2012-06-20 16:38:30 -070013021 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013022 hddLog(VOS_TRACE_LEVEL_ERROR,
13023 "%s: Invalid RTS Threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013024 __func__, rts_threshold);
13025 return -EINVAL;
13026 }
13027
13028 if (0 != ccmCfgSetInt(hHal, WNI_CFG_RTS_THRESHOLD,
13029 rts_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013030 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013031 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013032 hddLog(VOS_TRACE_LEVEL_ERROR,
13033 "%s: ccmCfgSetInt failed for rts_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013034 __func__, rts_threshold);
13035 return -EIO;
13036 }
13037
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013038 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set rts threshold %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013039 rts_threshold);
13040 }
13041
13042 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
13043 {
13044 u16 frag_threshold = (wiphy->frag_threshold == -1) ?
13045 WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX :
13046 wiphy->frag_threshold;
13047
13048 if ((WNI_CFG_FRAGMENTATION_THRESHOLD_STAMIN > frag_threshold)||
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013049 (WNI_CFG_FRAGMENTATION_THRESHOLD_STAMAX < frag_threshold) )
Jeff Johnson295189b2012-06-20 16:38:30 -070013050 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013051 hddLog(VOS_TRACE_LEVEL_ERROR,
13052 "%s: Invalid frag_threshold value %hu", __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -070013053 frag_threshold);
13054 return -EINVAL;
13055 }
13056
13057 if (0 != ccmCfgSetInt(hHal, WNI_CFG_FRAGMENTATION_THRESHOLD,
13058 frag_threshold, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013059 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013060 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013061 hddLog(VOS_TRACE_LEVEL_ERROR,
13062 "%s: ccmCfgSetInt failed for frag_threshold value %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013063 __func__, frag_threshold);
13064 return -EIO;
13065 }
13066
13067 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set frag threshold %hu", __func__,
13068 frag_threshold);
13069 }
13070
13071 if ((changed & WIPHY_PARAM_RETRY_SHORT)
13072 || (changed & WIPHY_PARAM_RETRY_LONG))
13073 {
13074 u8 retry_value = (changed & WIPHY_PARAM_RETRY_SHORT) ?
13075 wiphy->retry_short :
13076 wiphy->retry_long;
13077
13078 if ((WNI_CFG_LONG_RETRY_LIMIT_STAMIN > retry_value) ||
13079 (WNI_CFG_LONG_RETRY_LIMIT_STAMAX < retry_value))
13080 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013081 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013082 __func__, retry_value);
13083 return -EINVAL;
13084 }
13085
13086 if (changed & WIPHY_PARAM_RETRY_SHORT)
13087 {
13088 if (0 != ccmCfgSetInt(hHal, WNI_CFG_LONG_RETRY_LIMIT,
13089 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013090 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013091 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013092 hddLog(VOS_TRACE_LEVEL_ERROR,
13093 "%s: ccmCfgSetInt failed for long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013094 __func__, retry_value);
13095 return -EIO;
13096 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013097 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set long retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013098 __func__, retry_value);
13099 }
13100 else if (changed & WIPHY_PARAM_RETRY_SHORT)
13101 {
13102 if (0 != ccmCfgSetInt(hHal, WNI_CFG_SHORT_RETRY_LIMIT,
13103 retry_value, ccmCfgSetCallback,
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013104 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013105 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013106 hddLog(VOS_TRACE_LEVEL_ERROR,
13107 "%s: ccmCfgSetInt failed for short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013108 __func__, retry_value);
13109 return -EIO;
13110 }
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013111 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set short retry count %hu",
Jeff Johnson295189b2012-06-20 16:38:30 -070013112 __func__, retry_value);
13113 }
13114 }
13115
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013116 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013117 return 0;
13118}
13119
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013120static int wlan_hdd_cfg80211_set_wiphy_params(struct wiphy *wiphy,
13121 u32 changed)
13122{
13123 int ret;
13124
13125 vos_ssr_protect(__func__);
13126 ret = __wlan_hdd_cfg80211_set_wiphy_params(wiphy, changed);
13127 vos_ssr_unprotect(__func__);
13128
13129 return ret;
13130}
13131
Jeff Johnson295189b2012-06-20 16:38:30 -070013132/*
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013133 * FUNCTION: __wlan_hdd_cfg80211_set_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013134 * This function is used to set the txpower
13135 */
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013136static int __wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013137#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13138 struct wireless_dev *wdev,
13139#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013140#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013141 enum tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013142#else
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013143 enum nl80211_tx_power_setting type,
Jeff Johnson295189b2012-06-20 16:38:30 -070013144#endif
13145 int dbm)
13146{
13147 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013148 tHalHandle hHal = NULL;
Jeff Johnson295189b2012-06-20 16:38:30 -070013149 tSirMacAddr bssid = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
13150 tSirMacAddr selfMac = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013151 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013152
13153 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013154
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013155 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13156 TRACE_CODE_HDD_CFG80211_SET_TXPOWER,
13157 NO_SESSION, type ));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013158 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013159 if (0 != status)
13160 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013161 return status;
13162 }
13163
13164 hHal = pHddCtx->hHal;
13165
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013166 if (0 != ccmCfgSetInt(hHal, WNI_CFG_CURRENT_TX_POWER_LEVEL,
13167 dbm, ccmCfgSetCallback,
13168 eANI_BOOLEAN_TRUE))
Jeff Johnson295189b2012-06-20 16:38:30 -070013169 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013170 hddLog(VOS_TRACE_LEVEL_ERROR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013171 "%s: ccmCfgSetInt failed for tx power %hu", __func__, dbm);
13172 return -EIO;
13173 }
13174
13175 hddLog(VOS_TRACE_LEVEL_INFO_MED, "%s: set tx power level %d dbm", __func__,
13176 dbm);
13177
13178 switch(type)
13179 {
13180 case NL80211_TX_POWER_AUTOMATIC: /*automatically determine transmit power*/
13181 /* Fall through */
13182 case NL80211_TX_POWER_LIMITED: /*limit TX power by the mBm parameter*/
13183 if( sme_SetMaxTxPower(hHal, bssid, selfMac, dbm) != eHAL_STATUS_SUCCESS )
13184 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013185 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Setting maximum tx power failed",
13186 __func__);
13187 return -EIO;
Jeff Johnson295189b2012-06-20 16:38:30 -070013188 }
13189 break;
13190 case NL80211_TX_POWER_FIXED: /*fix TX power to the mBm parameter*/
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013191 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: NL80211_TX_POWER_FIXED not supported",
Jeff Johnson295189b2012-06-20 16:38:30 -070013192 __func__);
13193 return -EOPNOTSUPP;
13194 break;
13195 default:
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013196 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid power setting type %d",
13197 __func__, type);
Jeff Johnson295189b2012-06-20 16:38:30 -070013198 return -EIO;
13199 }
13200
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013201 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013202 return 0;
13203}
13204
Mahesh A Saptasagar179d2252014-06-02 21:32:21 +053013205static int wlan_hdd_cfg80211_set_txpower(struct wiphy *wiphy,
13206#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13207 struct wireless_dev *wdev,
13208#endif
13209#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13210 enum tx_power_setting type,
13211#else
13212 enum nl80211_tx_power_setting type,
13213#endif
13214 int dbm)
13215{
13216 int ret;
13217 vos_ssr_protect(__func__);
13218 ret = __wlan_hdd_cfg80211_set_txpower(wiphy,
13219#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13220 wdev,
13221#endif
13222#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
13223 type,
13224#else
13225 type,
13226#endif
13227 dbm);
13228 vos_ssr_unprotect(__func__);
13229
13230 return ret;
13231}
13232
Jeff Johnson295189b2012-06-20 16:38:30 -070013233/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013234 * FUNCTION: __wlan_hdd_cfg80211_get_txpower
Jeff Johnson295189b2012-06-20 16:38:30 -070013235 * This function is used to read the txpower
13236 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013237static int __wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
Yue Maf49ba872013-08-19 12:04:25 -070013238#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13239 struct wireless_dev *wdev,
13240#endif
13241 int *dbm)
Jeff Johnson295189b2012-06-20 16:38:30 -070013242{
13243
13244 hdd_adapter_t *pAdapter;
13245 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013246 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013247
Jeff Johnsone7245742012-09-05 17:12:55 -070013248 ENTER();
13249
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013250 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013251 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013252 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013253 *dbm = 0;
13254 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013255 }
13256
Jeff Johnson295189b2012-06-20 16:38:30 -070013257 pAdapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION);
13258 if (NULL == pAdapter)
13259 {
13260 hddLog(VOS_TRACE_LEVEL_FATAL, "%s: Not in station context " ,__func__);
13261 return -ENOENT;
13262 }
13263
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053013264 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13265 TRACE_CODE_HDD_CFG80211_GET_TXPOWER,
13266 pAdapter->sessionId, pAdapter->device_mode));
Jeff Johnson295189b2012-06-20 16:38:30 -070013267 wlan_hdd_get_classAstats(pAdapter);
13268 *dbm = pAdapter->hdd_stats.ClassA_stat.max_pwr;
13269
Jeff Johnsone7245742012-09-05 17:12:55 -070013270 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013271 return 0;
13272}
13273
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013274static int wlan_hdd_cfg80211_get_txpower(struct wiphy *wiphy,
13275#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13276 struct wireless_dev *wdev,
13277#endif
13278 int *dbm)
13279{
13280 int ret;
13281
13282 vos_ssr_protect(__func__);
13283 ret = __wlan_hdd_cfg80211_get_txpower(wiphy,
13284#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0)
13285 wdev,
13286#endif
13287 dbm);
13288 vos_ssr_unprotect(__func__);
13289
13290 return ret;
13291}
13292
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013293static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013294#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
13295 const u8* mac,
13296#else
13297 u8* mac,
13298#endif
13299 struct station_info *sinfo)
Jeff Johnson295189b2012-06-20 16:38:30 -070013300{
13301 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR( dev );
13302 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
13303 int ssidlen = pHddStaCtx->conn_info.SSID.SSID.length;
c_hpothu44ff4e02014-05-08 00:13:57 +053013304 tANI_U32 rate_flags;
Jeff Johnson295189b2012-06-20 16:38:30 -070013305
13306 hdd_context_t *pHddCtx = (hdd_context_t*) wiphy_priv(wiphy);
13307 hdd_config_t *pCfg = pHddCtx->cfg_ini;
Jeff Johnson295189b2012-06-20 16:38:30 -070013308
13309 tANI_U8 OperationalRates[CSR_DOT11_SUPPORTED_RATES_MAX];
13310 tANI_U32 ORLeng = CSR_DOT11_SUPPORTED_RATES_MAX;
13311 tANI_U8 ExtendedRates[CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX];
13312 tANI_U32 ERLeng = CSR_DOT11_EXTENDED_SUPPORTED_RATES_MAX;
13313 tANI_U8 MCSRates[SIZE_OF_BASIC_MCS_SET];
13314 tANI_U32 MCSLeng = SIZE_OF_BASIC_MCS_SET;
13315 tANI_U16 maxRate = 0;
13316 tANI_U16 myRate;
13317 tANI_U16 currentRate = 0;
13318 tANI_U8 maxSpeedMCS = 0;
13319 tANI_U8 maxMCSIdx = 0;
13320 tANI_U8 rateFlag = 1;
c_hpothu79aab322014-07-14 21:11:01 +053013321 tANI_U8 i, j, rssidx, mode=0;
Madan Mohan Koyyalamudic75be962012-10-18 19:19:03 -070013322 tANI_U16 temp;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013323 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013324
Leo Chang6f8870f2013-03-26 18:11:36 -070013325#ifdef WLAN_FEATURE_11AC
13326 tANI_U32 vht_mcs_map;
13327 eDataRate11ACMaxMcs vhtMaxMcs;
13328#endif /* WLAN_FEATURE_11AC */
13329
Jeff Johnsone7245742012-09-05 17:12:55 -070013330 ENTER();
13331
Jeff Johnson295189b2012-06-20 16:38:30 -070013332 if ((eConnectionState_Associated != pHddStaCtx->conn_info.connState) ||
13333 (0 == ssidlen))
13334 {
13335 hddLog(VOS_TRACE_LEVEL_INFO, "%s: Not associated or"
13336 " Invalid ssidlen, %d", __func__, ssidlen);
13337 /*To keep GUI happy*/
13338 return 0;
13339 }
13340
Mukul Sharma811205f2014-07-09 21:07:30 +053013341 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
13342 {
13343 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
13344 "%s: Roaming in progress, so unable to proceed this request", __func__);
13345 return 0;
13346 }
13347
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013348 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013349 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013350 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013351 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013352 }
13353
Jeff Johnson295189b2012-06-20 16:38:30 -070013354
Kiet Lam3b17fc82013-09-27 05:24:08 +053013355 wlan_hdd_get_rssi(pAdapter, &sinfo->signal);
13356 sinfo->filled |= STATION_INFO_SIGNAL;
13357
c_hpothu09f19542014-05-30 21:53:31 +053013358 wlan_hdd_get_station_stats(pAdapter);
13359 rate_flags = pAdapter->hdd_stats.ClassA_stat.tx_rate_flags;
13360
13361 /*overwrite rate_flags if MAX link-speed need to be reported*/
c_hpothu44ff4e02014-05-08 00:13:57 +053013362 if ((eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed) ||
13363 (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed &&
c_hpothu79aab322014-07-14 21:11:01 +053013364 sinfo->signal >= pCfg->linkSpeedRssiLow))
c_hpothu44ff4e02014-05-08 00:13:57 +053013365 {
13366 rate_flags = pAdapter->maxRateFlags;
13367 }
c_hpothu44ff4e02014-05-08 00:13:57 +053013368
Jeff Johnson295189b2012-06-20 16:38:30 -070013369 //convert to the UI units of 100kbps
13370 myRate = pAdapter->hdd_stats.ClassA_stat.tx_rate * 5;
13371
13372#ifdef LINKSPEED_DEBUG_ENABLED
Leo Chang6f8870f2013-03-26 18:11:36 -070013373 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 -070013374 sinfo->signal,
13375 pCfg->reportMaxLinkSpeed,
13376 myRate,
13377 (int) pCfg->linkSpeedRssiHigh,
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013378 (int) pCfg->linkSpeedRssiMid,
13379 (int) pCfg->linkSpeedRssiLow,
Leo Chang6f8870f2013-03-26 18:11:36 -070013380 (int) rate_flags,
13381 (int) pAdapter->hdd_stats.ClassA_stat.mcs_index);
Jeff Johnson295189b2012-06-20 16:38:30 -070013382#endif //LINKSPEED_DEBUG_ENABLED
13383
13384 if (eHDD_LINK_SPEED_REPORT_ACTUAL != pCfg->reportMaxLinkSpeed)
13385 {
13386 // we do not want to necessarily report the current speed
13387 if (eHDD_LINK_SPEED_REPORT_MAX == pCfg->reportMaxLinkSpeed)
13388 {
13389 // report the max possible speed
13390 rssidx = 0;
13391 }
13392 else if (eHDD_LINK_SPEED_REPORT_MAX_SCALED == pCfg->reportMaxLinkSpeed)
13393 {
13394 // report the max possible speed with RSSI scaling
13395 if (sinfo->signal >= pCfg->linkSpeedRssiHigh)
13396 {
13397 // report the max possible speed
13398 rssidx = 0;
13399 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013400 else if (sinfo->signal >= pCfg->linkSpeedRssiMid)
Jeff Johnson295189b2012-06-20 16:38:30 -070013401 {
13402 // report middle speed
13403 rssidx = 1;
13404 }
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013405 else if (sinfo->signal >= pCfg->linkSpeedRssiLow)
13406 {
13407 // report middle speed
13408 rssidx = 2;
13409 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013410 else
13411 {
13412 // report actual speed
Madan Mohan Koyyalamudi8df78d52012-11-02 12:30:06 -070013413 rssidx = 3;
Jeff Johnson295189b2012-06-20 16:38:30 -070013414 }
13415 }
13416 else
13417 {
13418 // unknown, treat as eHDD_LINK_SPEED_REPORT_MAX
13419 hddLog(VOS_TRACE_LEVEL_ERROR,
13420 "%s: Invalid value for reportMaxLinkSpeed: %u",
13421 __func__, pCfg->reportMaxLinkSpeed);
13422 rssidx = 0;
13423 }
13424
13425 maxRate = 0;
13426
13427 /* Get Basic Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013428 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_OPERATIONAL_RATE_SET,
13429 OperationalRates, &ORLeng))
13430 {
13431 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13432 /*To keep GUI happy*/
13433 return 0;
13434 }
13435
Jeff Johnson295189b2012-06-20 16:38:30 -070013436 for (i = 0; i < ORLeng; i++)
13437 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013438 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013439 {
13440 /* Validate Rate Set */
13441 if (supported_data_rate[j].beacon_rate_index == (OperationalRates[i] & 0x7F))
13442 {
13443 currentRate = supported_data_rate[j].supported_rate[rssidx];
13444 break;
13445 }
13446 }
13447 /* Update MAX rate */
13448 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13449 }
13450
13451 /* Get Extended Rate Set */
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013452 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_EXTENDED_OPERATIONAL_RATE_SET,
13453 ExtendedRates, &ERLeng))
13454 {
13455 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13456 /*To keep GUI happy*/
13457 return 0;
13458 }
13459
Jeff Johnson295189b2012-06-20 16:38:30 -070013460 for (i = 0; i < ERLeng; i++)
13461 {
Jeff Johnsone7245742012-09-05 17:12:55 -070013462 for (j = 0; j < (sizeof(supported_data_rate) / sizeof(supported_data_rate[0])); j ++)
Jeff Johnson295189b2012-06-20 16:38:30 -070013463 {
13464 if (supported_data_rate[j].beacon_rate_index == (ExtendedRates[i] & 0x7F))
13465 {
13466 currentRate = supported_data_rate[j].supported_rate[rssidx];
13467 break;
13468 }
13469 }
13470 /* Update MAX rate */
13471 maxRate = (currentRate > maxRate)?currentRate:maxRate;
13472 }
c_hpothu79aab322014-07-14 21:11:01 +053013473
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013474 /* Get MCS Rate Set --
Kaushik, Sushantdc304d82014-01-22 10:58:37 +053013475 Only if we are always reporting max speed (or)
Kiet Lamb69f8dc2013-11-15 15:34:27 +053013476 if we have good rssi */
c_hpothu79aab322014-07-14 21:11:01 +053013477 if ((3 != rssidx) && !(rate_flags & eHAL_TX_RATE_LEGACY))
Jeff Johnson295189b2012-06-20 16:38:30 -070013478 {
c_hpothu79aab322014-07-14 21:11:01 +053013479 if (rate_flags & eHAL_TX_RATE_VHT80)
13480 mode = 2;
13481 else if (rate_flags & (eHAL_TX_RATE_VHT40 | eHAL_TX_RATE_HT40))
13482 mode = 1;
13483 else
13484 mode = 0;
13485
Gopichand Nakkala05ab1322013-02-15 11:28:38 +053013486 if (0 != ccmCfgGetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_CURRENT_MCS_SET,
13487 MCSRates, &MCSLeng))
13488 {
13489 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: ccm api returned failure", __func__);
13490 /*To keep GUI happy*/
13491 return 0;
13492 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013493 rateFlag = 0;
Leo Chang6f8870f2013-03-26 18:11:36 -070013494#ifdef WLAN_FEATURE_11AC
13495 /* VHT80 rate has seperate rate table */
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013496 if (rate_flags & (eHAL_TX_RATE_VHT20|eHAL_TX_RATE_VHT40|eHAL_TX_RATE_VHT80))
Jeff Johnson295189b2012-06-20 16:38:30 -070013497 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013498 ccmCfgGetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), WNI_CFG_VHT_TX_MCS_MAP, &vht_mcs_map);
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013499 vhtMaxMcs = (eDataRate11ACMaxMcs)(vht_mcs_map & DATA_RATE_11AC_MCS_MASK );
Leo Chang6f8870f2013-03-26 18:11:36 -070013500 if (rate_flags & eHAL_TX_RATE_SGI)
Jeff Johnson295189b2012-06-20 16:38:30 -070013501 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013502 rateFlag |= 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013503 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013504 if (DATA_RATE_11AC_MAX_MCS_7 == vhtMaxMcs)
Jeff Johnson295189b2012-06-20 16:38:30 -070013505 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013506 maxMCSIdx = 7;
13507 }
13508 else if (DATA_RATE_11AC_MAX_MCS_8 == vhtMaxMcs)
13509 {
13510 maxMCSIdx = 8;
13511 }
13512 else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs)
13513 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013514 //VHT20 is supporting 0~8
13515 if (rate_flags & eHAL_TX_RATE_VHT20)
13516 maxMCSIdx = 8;
13517 else
13518 maxMCSIdx = 9;
Leo Chang6f8870f2013-03-26 18:11:36 -070013519 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013520
c_hpothu79aab322014-07-14 21:11:01 +053013521 if (0 != rssidx)/*check for scaled */
13522 {
13523 //get middle rate MCS index if rssi=1/2
13524 for (i=0; i <= maxMCSIdx; i++)
13525 {
13526 if (sinfo->signal <= rssiMcsTbl[mode][i])
13527 {
13528 maxMCSIdx = i;
13529 break;
13530 }
13531 }
13532 }
13533
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013534 if (rate_flags & eHAL_TX_RATE_VHT80)
13535 {
13536 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT80_rate[rateFlag];
13537 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT80_rate[rateFlag];
13538 }
13539 else if (rate_flags & eHAL_TX_RATE_VHT40)
13540 {
13541 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT40_rate[rateFlag];
13542 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT40_rate[rateFlag];
13543 }
13544 else if (rate_flags & eHAL_TX_RATE_VHT20)
13545 {
13546 currentRate = supported_vht_mcs_rate[pAdapter->hdd_stats.ClassA_stat.mcs_index].supported_VHT20_rate[rateFlag];
13547 maxRate = supported_vht_mcs_rate[maxMCSIdx].supported_VHT20_rate[rateFlag];
13548 }
13549
Leo Chang6f8870f2013-03-26 18:11:36 -070013550 maxSpeedMCS = 1;
13551 if (currentRate > maxRate)
13552 {
13553 maxRate = currentRate;
13554 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013555
Leo Chang6f8870f2013-03-26 18:11:36 -070013556 }
13557 else
13558#endif /* WLAN_FEATURE_11AC */
13559 {
13560 if (rate_flags & eHAL_TX_RATE_HT40)
13561 {
13562 rateFlag |= 1;
13563 }
13564 if (rate_flags & eHAL_TX_RATE_SGI)
13565 {
13566 rateFlag |= 2;
13567 }
13568
Girish Gowli01abcee2014-07-31 20:18:55 +053013569 temp = sizeof(supported_mcs_rate) / sizeof(supported_mcs_rate[0]);
c_hpothu79aab322014-07-14 21:11:01 +053013570 if (rssidx == 1 || rssidx == 2)
13571 {
13572 //get middle rate MCS index if rssi=1/2
13573 for (i=0; i <= 7; i++)
13574 {
13575 if (sinfo->signal <= rssiMcsTbl[mode][i])
13576 {
13577 temp = i+1;
13578 break;
13579 }
13580 }
13581 }
c_hpothu79aab322014-07-14 21:11:01 +053013582
13583 for (i = 0; i < MCSLeng; i++)
13584 {
Leo Chang6f8870f2013-03-26 18:11:36 -070013585 for (j = 0; j < temp; j++)
13586 {
13587 if (supported_mcs_rate[j].beacon_rate_index == MCSRates[i])
13588 {
13589 currentRate = supported_mcs_rate[j].supported_rate[rateFlag];
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053013590 maxMCSIdx = supported_mcs_rate[j].beacon_rate_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013591 break;
13592 }
13593 }
13594 if ((j < temp) && (currentRate > maxRate))
13595 {
13596 maxRate = currentRate;
Leo Chang6f8870f2013-03-26 18:11:36 -070013597 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013598 }
Hanumantha Reddy Pothulafa623742015-06-16 14:08:24 +053013599 maxSpeedMCS = 1;
Jeff Johnson295189b2012-06-20 16:38:30 -070013600 }
13601 }
13602
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013603 else if (!(rate_flags & eHAL_TX_RATE_LEGACY))
13604 {
13605 maxRate = myRate;
13606 maxSpeedMCS = 1;
13607 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13608 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013609 // make sure we report a value at least as big as our current rate
c_hpothu79aab322014-07-14 21:11:01 +053013610 if ((maxRate < myRate) || (0 == maxRate))
Jeff Johnson295189b2012-06-20 16:38:30 -070013611 {
13612 maxRate = myRate;
13613 if (rate_flags & eHAL_TX_RATE_LEGACY)
13614 {
13615 maxSpeedMCS = 0;
13616 }
13617 else
13618 {
13619 maxSpeedMCS = 1;
13620 maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index;
13621 }
13622 }
13623
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013624 if (rate_flags & eHAL_TX_RATE_LEGACY)
Jeff Johnson295189b2012-06-20 16:38:30 -070013625 {
13626 sinfo->txrate.legacy = maxRate;
13627#ifdef LINKSPEED_DEBUG_ENABLED
13628 pr_info("Reporting legacy rate %d\n", sinfo->txrate.legacy);
13629#endif //LINKSPEED_DEBUG_ENABLED
13630 }
13631 else
13632 {
13633 sinfo->txrate.mcs = maxMCSIdx;
Leo Chang6f8870f2013-03-26 18:11:36 -070013634#ifdef WLAN_FEATURE_11AC
13635 sinfo->txrate.nss = 1;
13636 if (rate_flags & eHAL_TX_RATE_VHT80)
13637 {
13638 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013639 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
Leo Chang6f8870f2013-03-26 18:11:36 -070013640 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013641 else if (rate_flags & eHAL_TX_RATE_VHT40)
Leo Chang6f8870f2013-03-26 18:11:36 -070013642 {
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013643 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13644 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13645 }
13646 else if (rate_flags & eHAL_TX_RATE_VHT20)
13647 {
13648 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13649 }
13650#endif /* WLAN_FEATURE_11AC */
13651 if (rate_flags & (eHAL_TX_RATE_HT20 | eHAL_TX_RATE_HT40))
13652 {
13653 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13654 if (rate_flags & eHAL_TX_RATE_HT40)
13655 {
13656 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13657 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013658 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013659 if (rate_flags & eHAL_TX_RATE_SGI)
13660 {
13661 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13662 }
Gopichand Nakkala4c705372013-04-24 13:20:33 +053013663
Jeff Johnson295189b2012-06-20 16:38:30 -070013664#ifdef LINKSPEED_DEBUG_ENABLED
13665 pr_info("Reporting MCS rate %d flags %x\n",
13666 sinfo->txrate.mcs,
13667 sinfo->txrate.flags );
13668#endif //LINKSPEED_DEBUG_ENABLED
13669 }
13670 }
13671 else
13672 {
13673 // report current rate instead of max rate
13674
13675 if (rate_flags & eHAL_TX_RATE_LEGACY)
13676 {
13677 //provide to the UI in units of 100kbps
13678 sinfo->txrate.legacy = myRate;
13679#ifdef LINKSPEED_DEBUG_ENABLED
13680 pr_info("Reporting actual legacy rate %d\n", sinfo->txrate.legacy);
13681#endif //LINKSPEED_DEBUG_ENABLED
13682 }
13683 else
13684 {
13685 //must be MCS
13686 sinfo->txrate.mcs = pAdapter->hdd_stats.ClassA_stat.mcs_index;
Leo Chang6f8870f2013-03-26 18:11:36 -070013687#ifdef WLAN_FEATURE_11AC
13688 sinfo->txrate.nss = 1;
13689 if (rate_flags & eHAL_TX_RATE_VHT80)
13690 {
13691 sinfo->txrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
13692 }
13693 else
13694#endif /* WLAN_FEATURE_11AC */
13695 {
13696 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
13697 }
Jeff Johnson295189b2012-06-20 16:38:30 -070013698 if (rate_flags & eHAL_TX_RATE_SGI)
13699 {
13700 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
13701 }
13702 if (rate_flags & eHAL_TX_RATE_HT40)
13703 {
13704 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
13705 }
Leo Chang6f8870f2013-03-26 18:11:36 -070013706#ifdef WLAN_FEATURE_11AC
13707 else if (rate_flags & eHAL_TX_RATE_VHT80)
13708 {
13709 sinfo->txrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
13710 }
13711#endif /* WLAN_FEATURE_11AC */
Jeff Johnson295189b2012-06-20 16:38:30 -070013712#ifdef LINKSPEED_DEBUG_ENABLED
13713 pr_info("Reporting actual MCS rate %d flags %x\n",
13714 sinfo->txrate.mcs,
13715 sinfo->txrate.flags );
13716#endif //LINKSPEED_DEBUG_ENABLED
13717 }
13718 }
13719 sinfo->filled |= STATION_INFO_TX_BITRATE;
13720
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013721 sinfo->tx_packets =
13722 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[0] +
13723 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[1] +
13724 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[2] +
13725 pAdapter->hdd_stats.summary_stat.tx_frm_cnt[3];
13726
13727 sinfo->tx_retries =
13728 pAdapter->hdd_stats.summary_stat.retry_cnt[0] +
13729 pAdapter->hdd_stats.summary_stat.retry_cnt[1] +
13730 pAdapter->hdd_stats.summary_stat.retry_cnt[2] +
13731 pAdapter->hdd_stats.summary_stat.retry_cnt[3];
13732
13733 sinfo->tx_failed =
13734 pAdapter->hdd_stats.summary_stat.fail_cnt[0] +
13735 pAdapter->hdd_stats.summary_stat.fail_cnt[1] +
13736 pAdapter->hdd_stats.summary_stat.fail_cnt[2] +
13737 pAdapter->hdd_stats.summary_stat.fail_cnt[3];
13738
13739 sinfo->filled |=
13740 STATION_INFO_TX_PACKETS |
13741 STATION_INFO_TX_RETRIES |
13742 STATION_INFO_TX_FAILED;
13743
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013744 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13745 TRACE_CODE_HDD_CFG80211_GET_STA,
13746 pAdapter->sessionId, maxRate));
Madan Mohan Koyyalamudi4d4d2812012-09-24 14:08:29 -070013747 EXIT();
13748 return 0;
Jeff Johnson295189b2012-06-20 16:38:30 -070013749}
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013750#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
13751static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
13752 const u8* mac, struct station_info *sinfo)
13753#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013754static int wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
13755 u8* mac, struct station_info *sinfo)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053013756#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013757{
13758 int ret;
13759
13760 vos_ssr_protect(__func__);
13761 ret = __wlan_hdd_cfg80211_get_station(wiphy, dev, mac, sinfo);
13762 vos_ssr_unprotect(__func__);
13763
13764 return ret;
13765}
13766
13767static int __wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
Sameer Thalappilc9f26e92013-06-07 10:11:06 -070013768 struct net_device *dev, bool mode, int timeout)
Jeff Johnson295189b2012-06-20 16:38:30 -070013769{
13770 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013771 hdd_context_t *pHddCtx;
Jeff Johnson295189b2012-06-20 16:38:30 -070013772 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013773 int status;
Jeff Johnson295189b2012-06-20 16:38:30 -070013774
Jeff Johnsone7245742012-09-05 17:12:55 -070013775 ENTER();
13776
Jeff Johnson295189b2012-06-20 16:38:30 -070013777 if (NULL == pAdapter)
13778 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080013779 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013780 return -ENODEV;
13781 }
13782
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013783 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13784 TRACE_CODE_HDD_CFG80211_SET_POWER_MGMT,
13785 pAdapter->sessionId, timeout));
13786
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013787 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013788 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013789 if (0 != status)
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013790 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013791 return status;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013792 }
13793
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013794 if ((DRIVER_POWER_MODE_AUTO == !mode) &&
13795 (TRUE == pHddCtx->hdd_wlan_suspended) &&
13796 (pHddCtx->cfg_ini->fhostArpOffload) &&
13797 (eConnectionState_Associated ==
13798 (WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))->conn_info.connState))
13799 {
Amar Singhald53568e2013-09-26 11:03:45 -070013800
13801 hddLog(VOS_TRACE_LEVEL_INFO,
13802 "offload: in cfg80211_set_power_mgmt, calling arp offload");
Gopichand Nakkalab03e8082013-05-30 18:09:25 +053013803 vos_status = hdd_conf_arp_offload(pAdapter, TRUE);
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013804 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13805 {
13806 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain6d2a3322013-11-17 19:50:10 -080013807 "%s:Failed to enable ARPOFFLOAD Feature %d",
Gopichand Nakkala20c4c042013-04-19 22:08:55 +053013808 __func__, vos_status);
13809 }
13810 }
13811
Jeff Johnson295189b2012-06-20 16:38:30 -070013812 /**The get power cmd from the supplicant gets updated by the nl only
13813 *on successful execution of the function call
13814 *we are oppositely mapped w.r.t mode in the driver
13815 **/
13816 vos_status = wlan_hdd_enter_bmps(pAdapter, !mode);
13817
13818 if (VOS_STATUS_E_FAILURE == vos_status)
13819 {
c_hpothu6ff1c3c2013-10-01 19:01:57 +053013820 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13821 "%s: failed to enter bmps mode", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013822 return -EINVAL;
13823 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013824 EXIT();
Jeff Johnson295189b2012-06-20 16:38:30 -070013825 return 0;
13826}
13827
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013828static int wlan_hdd_cfg80211_set_power_mgmt(struct wiphy *wiphy,
13829 struct net_device *dev, bool mode, int timeout)
13830{
13831 int ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013832
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053013833 vos_ssr_protect(__func__);
13834 ret = __wlan_hdd_cfg80211_set_power_mgmt(wiphy, dev, mode, timeout);
13835 vos_ssr_unprotect(__func__);
13836
13837 return ret;
13838}
Jeff Johnson295189b2012-06-20 16:38:30 -070013839#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013840static int __wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
13841 struct net_device *netdev,
13842 u8 key_index)
13843{
13844 ENTER();
13845 return 0;
13846}
13847
Jeff Johnson295189b2012-06-20 16:38:30 -070013848static int wlan_hdd_set_default_mgmt_key(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013849 struct net_device *netdev,
13850 u8 key_index)
13851{
13852 int ret;
13853 vos_ssr_protect(__func__);
13854 ret = __wlan_hdd_set_default_mgmt_key(wiphy, netdev, key_index);
13855 vos_ssr_unprotect(__func__);
13856 return ret;
13857}
13858#endif //LINUX_VERSION_CODE
13859
13860#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13861static int __wlan_hdd_set_txq_params(struct wiphy *wiphy,
13862 struct net_device *dev,
13863 struct ieee80211_txq_params *params)
13864{
13865 ENTER();
13866 return 0;
13867}
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)
Jeff Johnson295189b2012-06-20 16:38:30 -070013871{
Jeff Johnsone7245742012-09-05 17:12:55 -070013872 ENTER();
Jeff Johnson295189b2012-06-20 16:38:30 -070013873 return 0;
13874}
Gopichand Nakkala747461f2013-04-24 19:24:45 +053013875#endif //LINUX_VERSION_CODE
Jeff Johnson295189b2012-06-20 16:38:30 -070013876
13877#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0))
13878static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013879 struct net_device *dev,
13880 struct ieee80211_txq_params *params)
Jeff Johnson295189b2012-06-20 16:38:30 -070013881{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013882 int ret;
13883
13884 vos_ssr_protect(__func__);
13885 ret = __wlan_hdd_set_txq_params(wiphy, dev, params);
13886 vos_ssr_unprotect(__func__);
13887 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013888}
13889#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
13890static int wlan_hdd_set_txq_params(struct wiphy *wiphy,
13891 struct ieee80211_txq_params *params)
13892{
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013893 int ret;
13894
13895 vos_ssr_protect(__func__);
13896 ret = __wlan_hdd_set_txq_params(wiphy, params);
13897 vos_ssr_unprotect(__func__);
13898 return ret;
Jeff Johnson295189b2012-06-20 16:38:30 -070013899}
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053013900#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070013901
Naresh Jayaram69e3f282014-10-14 12:29:12 +053013902static int __wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013903 struct net_device *dev,
13904 struct tagCsrDelStaParams *pDelStaParams)
Jeff Johnson295189b2012-06-20 16:38:30 -070013905{
13906 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013907 hdd_context_t *pHddCtx;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013908 VOS_STATUS vos_status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013909 int status;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013910 v_U8_t staId;
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013911 v_CONTEXT_t pVosContext = NULL;
13912 ptSapContext pSapCtx = NULL;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053013913
Jeff Johnsone7245742012-09-05 17:12:55 -070013914 ENTER();
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013915
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013916 if ( NULL == pAdapter )
Jeff Johnson295189b2012-06-20 16:38:30 -070013917 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013918 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson295189b2012-06-20 16:38:30 -070013919 return -EINVAL;
13920 }
13921
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053013922 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
13923 TRACE_CODE_HDD_CFG80211_DEL_STA,
13924 pAdapter->sessionId, pAdapter->device_mode));
13925
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013926 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
13927 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013928 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013929 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053013930 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070013931 }
13932
Jeff Johnson295189b2012-06-20 16:38:30 -070013933 if ( (WLAN_HDD_SOFTAP == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013934 || (WLAN_HDD_P2P_GO == pAdapter->device_mode)
Jeff Johnson295189b2012-06-20 16:38:30 -070013935 )
13936 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013937 pVosContext = ( WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
13938 pSapCtx = VOS_GET_SAP_CB(pVosContext);
13939 if(pSapCtx == NULL){
13940 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
13941 FL("psapCtx is NULL"));
13942 return -ENOENT;
13943 }
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013944 if (vos_is_macaddr_broadcast((v_MACADDR_t *)pDelStaParams->peerMacAddr))
Jeff Johnson295189b2012-06-20 16:38:30 -070013945 {
13946 v_U16_t i;
13947 for(i = 0; i < WLAN_MAX_STA_COUNT; i++)
13948 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013949 if ((pSapCtx->aStaInfo[i].isUsed) &&
13950 (!pSapCtx->aStaInfo[i].isDeauthInProgress))
Jeff Johnson295189b2012-06-20 16:38:30 -070013951 {
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013952 vos_mem_copy(pDelStaParams->peerMacAddr,
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013953 pSapCtx->aStaInfo[i].macAddrSTA.bytes,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013954 ETHER_ADDR_LEN);
13955
Jeff Johnson295189b2012-06-20 16:38:30 -070013956 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013957 "%s: Delete STA with MAC::"
13958 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013959 __func__,
13960 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
13961 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Rajesh Chauhan18488fc2013-08-22 10:15:03 -070013962 if (VOS_IS_STATUS_SUCCESS(vos_status))
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013963 pSapCtx->aStaInfo[i].isDeauthInProgress = TRUE;
Jeff Johnson295189b2012-06-20 16:38:30 -070013964 }
13965 }
13966 }
13967 else
13968 {
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013969
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013970 vos_status = hdd_softap_GetStaId(pAdapter,
13971 (v_MACADDR_t *)pDelStaParams->peerMacAddr, &staId);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013972 if (!VOS_IS_STATUS_SUCCESS(vos_status))
13973 {
13974 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013975 "%s: Skip this DEL STA as this is not used::"
13976 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013977 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013978 return -ENOENT;
13979 }
13980
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013981 if( pSapCtx->aStaInfo[staId].isDeauthInProgress == TRUE)
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013982 {
13983 hddLog(VOS_TRACE_LEVEL_INFO,
Arif Hussain24bafea2013-11-15 15:10:03 -080013984 "%s: Skip this DEL STA as deauth is in progress::"
13985 MAC_ADDRESS_STR,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013986 __func__, MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013987 return -ENOENT;
13988 }
13989
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053013990 pSapCtx->aStaInfo[staId].isDeauthInProgress = TRUE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013991
Jeff Johnson295189b2012-06-20 16:38:30 -070013992 hddLog(VOS_TRACE_LEVEL_INFO,
13993 "%s: Delete STA with MAC::"
Arif Hussain24bafea2013-11-15 15:10:03 -080013994 MAC_ADDRESS_STR,
Jeff Johnson295189b2012-06-20 16:38:30 -070013995 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013996 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013997
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053013998 vos_status = hdd_softap_sta_deauth(pAdapter, pDelStaParams);
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080013999 if (!VOS_IS_STATUS_SUCCESS(vos_status))
14000 {
Sachin Ahujabcb0b7e2014-11-07 13:01:24 +053014001 pSapCtx->aStaInfo[staId].isDeauthInProgress = FALSE;
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014002 hddLog(VOS_TRACE_LEVEL_INFO,
14003 "%s: STA removal failed for ::"
Arif Hussain24bafea2013-11-15 15:10:03 -080014004 MAC_ADDRESS_STR,
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014005 __func__,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014006 MAC_ADDR_ARRAY(pDelStaParams->peerMacAddr));
Madan Mohan Koyyalamudicd784992013-01-11 15:30:36 -080014007 return -ENOENT;
14008 }
14009
Jeff Johnson295189b2012-06-20 16:38:30 -070014010 }
14011 }
14012
14013 EXIT();
14014
14015 return 0;
14016}
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014017
14018#ifdef CFG80211_DEL_STA_V2
14019static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14020 struct net_device *dev,
14021 struct station_del_parameters *param)
14022#else
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014023#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14024static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14025 struct net_device *dev, const u8 *mac)
14026#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014027static int wlan_hdd_cfg80211_del_station(struct wiphy *wiphy,
14028 struct net_device *dev, u8 *mac)
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014029#endif
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014030#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014031{
14032 int ret;
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014033 struct tagCsrDelStaParams delStaParams;
Jeff Johnson295189b2012-06-20 16:38:30 -070014034
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014035 vos_ssr_protect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014036
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014037#ifdef CFG80211_DEL_STA_V2
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014038 if (NULL == param) {
14039 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid argumet passed", __func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053014040 vos_ssr_unprotect(__func__);
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014041 return -EINVAL;
14042 }
14043
14044 WLANSAP_PopulateDelStaParams(param->mac, param->reason_code,
14045 param->subtype, &delStaParams);
14046
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014047#else
Sushant Kaushik4cd28f62014-12-26 14:23:50 +053014048 WLANSAP_PopulateDelStaParams(mac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014049 (SIR_MAC_MGMT_DEAUTH >> 4), &delStaParams);
Naresh Jayaram69e3f282014-10-14 12:29:12 +053014050#endif
Hanumantha Reddy Pothulabfd06f72014-10-31 14:03:37 +053014051 ret = __wlan_hdd_cfg80211_del_station(wiphy, dev, &delStaParams);
14052
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014053 vos_ssr_unprotect(__func__);
14054
14055 return ret;
14056}
14057
14058static int __wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014059 struct net_device *dev,
14060#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
14061 const u8 *mac,
14062#else
14063 u8 *mac,
14064#endif
14065 struct station_parameters *params)
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014066{
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014067 hdd_adapter_t *pAdapter;
14068 hdd_context_t *pHddCtx;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014069 int status = -EPERM;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014070#ifdef FEATURE_WLAN_TDLS
14071 u32 mask, set;
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014072
Hoonki Lee11f7dda2013-02-14 16:55:44 -080014073 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014074
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014075 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14076 if (NULL == pAdapter)
14077 {
14078 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14079 "%s: Adapter is NULL",__func__);
14080 return -EINVAL;
14081 }
14082 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14083 status = wlan_hdd_validate_context(pHddCtx);
14084 if (0 != status)
14085 {
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014086 return status;
14087 }
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014088
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014089 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14090 TRACE_CODE_HDD_CFG80211_ADD_STA,
14091 pAdapter->sessionId, params->listen_interval));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014092 mask = params->sta_flags_mask;
14093
14094 set = params->sta_flags_set;
14095
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053014096 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070014097 "%s: mask 0x%x set 0x%x " MAC_ADDRESS_STR,
14098 __func__, mask, set, MAC_ADDR_ARRAY(mac));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014099
14100 if (mask & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
14101 if (set & BIT(NL80211_STA_FLAG_TDLS_PEER)) {
Gopichand Nakkala681989c2013-03-06 22:27:48 -080014102 status = wlan_hdd_tdls_add_station(wiphy, dev, mac, 0, NULL);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014103 }
14104 }
14105#endif
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014106 EXIT();
Gopichand Nakkalab977a972013-02-18 19:15:09 -080014107 return status;
Jeff Johnson295189b2012-06-20 16:38:30 -070014108}
14109
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014110#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
14111static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14112 struct net_device *dev, const u8 *mac,
14113 struct station_parameters *params)
14114#else
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014115static int wlan_hdd_cfg80211_add_station(struct wiphy *wiphy,
14116 struct net_device *dev, u8 *mac, struct station_parameters *params)
Anand N Sunkadb3ab97d2015-07-29 09:58:13 +053014117#endif
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014118{
14119 int ret;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014120
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014121 vos_ssr_protect(__func__);
14122 ret = __wlan_hdd_cfg80211_add_station(wiphy, dev, mac, params);
14123 vos_ssr_unprotect(__func__);
14124
14125 return ret;
14126}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014127#ifdef FEATURE_WLAN_LFR
Wilson Yang6507c4e2013-10-01 20:11:19 -070014128
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014129static int __wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
Jeff Johnsond13512a2012-07-17 11:42:19 -070014130 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014131{
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014132 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14133 tHalHandle halHandle;
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014134 eHalStatus result;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014135 int status;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014136 hdd_context_t *pHddCtx;
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014137 tPmkidCacheInfo pmk_id;
Jeff Johnsone7245742012-09-05 17:12:55 -070014138
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014139 ENTER();
14140
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014141 // Validate pAdapter
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014142 if ( NULL == pAdapter )
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014143 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014144 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014145 return -EINVAL;
14146 }
14147
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014148 if (!pmksa) {
14149 hddLog(LOGE, FL("pmksa is NULL"));
14150 return -EINVAL;
14151 }
14152
14153 if (!pmksa->bssid || !pmksa->pmkid) {
14154 hddLog(LOGE, FL("pmksa->bssid(%p) or pmksa->pmkid(%p) is NULL"),
14155 pmksa->bssid, pmksa->pmkid);
14156 return -EINVAL;
14157 }
14158
14159 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: set PMKSA for " MAC_ADDRESS_STR,
14160 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14161
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014162 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14163 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014164 if (0 != status)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014165 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053014166 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014167 }
14168
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014169 // Retrieve halHandle
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014170 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14171
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014172 vos_mem_copy(pmk_id.BSSID, pmksa->bssid, ETHER_ADDR_LEN);
14173 vos_mem_copy(pmk_id.PMKID, pmksa->pmkid, CSR_RSN_PMKID_SIZE);
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014174
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014175 /* Add to the PMKSA ID Cache in CSR */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053014176 result = sme_RoamSetPMKIDCache(halHandle,pAdapter->sessionId,
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014177 &pmk_id, 1, FALSE);
14178
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014179 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14180 TRACE_CODE_HDD_CFG80211_SET_PMKSA,
14181 pAdapter->sessionId, result));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014182
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014183 EXIT();
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014184 return HAL_STATUS_SUCCESS(result) ? 0 : -EINVAL;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014185}
14186
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014187static int wlan_hdd_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
14188 struct cfg80211_pmksa *pmksa)
14189{
14190 int ret;
14191
14192 vos_ssr_protect(__func__);
14193 ret = __wlan_hdd_cfg80211_set_pmksa(wiphy, dev, pmksa);
14194 vos_ssr_unprotect(__func__);
14195
14196 return ret;
14197}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014198
Wilson Yang6507c4e2013-10-01 20:11:19 -070014199
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014200static int __wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
Wilson Yang6507c4e2013-10-01 20:11:19 -070014201 struct cfg80211_pmksa *pmksa)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014202{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014203 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14204 tHalHandle halHandle;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014205 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014206 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014207
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014208 ENTER();
14209
Wilson Yang6507c4e2013-10-01 20:11:19 -070014210 /* Validate pAdapter */
14211 if (NULL == pAdapter)
14212 {
14213 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Adapter" ,__func__);
14214 return -EINVAL;
14215 }
14216
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014217 if (!pmksa) {
14218 hddLog(LOGE, FL("pmksa is NULL"));
14219 return -EINVAL;
14220 }
14221
14222 if (!pmksa->bssid) {
14223 hddLog(LOGE, FL("pmksa->bssid is NULL"));
14224 return -EINVAL;
14225 }
14226
Kiet Lam98c46a12014-10-31 15:34:57 -070014227 hddLog(VOS_TRACE_LEVEL_DEBUG, "%s: deleting PMKSA for " MAC_ADDRESS_STR,
14228 __func__, MAC_ADDR_ARRAY(pmksa->bssid));
14229
Wilson Yang6507c4e2013-10-01 20:11:19 -070014230 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14231 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014232 if (0 != status)
14233 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014234 return status;
14235 }
14236
14237 /*Retrieve halHandle*/
14238 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14239
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014240 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14241 TRACE_CODE_HDD_CFG80211_DEL_PMKSA,
14242 pAdapter->sessionId, 0));
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014243 /* Delete the PMKID CSR cache */
14244 if (eHAL_STATUS_SUCCESS !=
14245 sme_RoamDelPMKIDfromCache(halHandle,
14246 pAdapter->sessionId, pmksa->bssid, FALSE)) {
14247 hddLog(LOGE, FL("Failed to delete PMKSA for "MAC_ADDRESS_STR),
14248 MAC_ADDR_ARRAY(pmksa->bssid));
14249 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014250 }
14251
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014252 EXIT();
14253 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014254}
14255
Wilson Yang6507c4e2013-10-01 20:11:19 -070014256
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014257static int wlan_hdd_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
14258 struct cfg80211_pmksa *pmksa)
14259{
14260 int ret;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014261
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014262 vos_ssr_protect(__func__);
14263 ret = __wlan_hdd_cfg80211_del_pmksa(wiphy, dev, pmksa);
14264 vos_ssr_unprotect(__func__);
14265
14266 return ret;
14267
14268}
14269
14270static int __wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014271{
Wilson Yang6507c4e2013-10-01 20:11:19 -070014272 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14273 tHalHandle halHandle;
14274 hdd_context_t *pHddCtx;
Wilson Yangef657d32014-01-15 19:19:23 -080014275 int status = 0;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014276
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014277 ENTER();
Wilson Yang6507c4e2013-10-01 20:11:19 -070014278
14279 /* Validate pAdapter */
14280 if (NULL == pAdapter)
14281 {
14282 hddLog(VOS_TRACE_LEVEL_ERROR,
14283 "%s: Invalid Adapter" ,__func__);
14284 return -EINVAL;
14285 }
14286
14287 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14288 status = wlan_hdd_validate_context(pHddCtx);
Wilson Yang6507c4e2013-10-01 20:11:19 -070014289 if (0 != status)
14290 {
Wilson Yang6507c4e2013-10-01 20:11:19 -070014291 return status;
14292 }
14293
14294 /*Retrieve halHandle*/
14295 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
14296
Kanchanapally, Vidyullatha2633ace2014-09-25 15:16:50 +053014297 /* Flush the PMKID cache in CSR */
14298 if (eHAL_STATUS_SUCCESS !=
14299 sme_RoamDelPMKIDfromCache(halHandle, pAdapter->sessionId, NULL, TRUE)) {
14300 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Cannot flush PMKIDCache"));
14301 status = -EINVAL;
Wilson Yang6507c4e2013-10-01 20:11:19 -070014302 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014303 EXIT();
Wilson Yangef657d32014-01-15 19:19:23 -080014304 return status;
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014305}
Mahesh A Saptasagarf7418d72014-06-02 14:48:54 +053014306
14307static int wlan_hdd_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
14308{
14309 int ret;
14310
14311 vos_ssr_protect(__func__);
14312 ret = __wlan_hdd_cfg80211_flush_pmksa(wiphy, dev);
14313 vos_ssr_unprotect(__func__);
14314
14315 return ret;
14316}
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014317#endif
14318
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014319#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014320static int __wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14321 struct net_device *dev,
14322 struct cfg80211_update_ft_ies_params *ftie)
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014323{
14324 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14325 hdd_station_ctx_t *pHddStaCtx;
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014326 hdd_context_t *pHddCtx;
14327 int ret = 0;
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014328
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014329 ENTER();
14330
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014331 if (NULL == pAdapter)
14332 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014333 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Adapter is NULL", __func__);
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014334 return -ENODEV;
14335 }
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014336 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14337 ret = wlan_hdd_validate_context(pHddCtx);
14338 if (0 != ret)
14339 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053014340 return ret;
14341 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014342 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053014343 if (NULL == pHddStaCtx)
14344 {
14345 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: STA Context is NULL", __func__);
14346 return -EINVAL;
14347 }
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014348
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053014349 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14350 TRACE_CODE_HDD_CFG80211_UPDATE_FT_IES,
14351 pAdapter->sessionId, pHddStaCtx->conn_info.connState));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014352 // Added for debug on reception of Re-assoc Req.
14353 if (eConnectionState_Associated != pHddStaCtx->conn_info.connState)
14354 {
Arif Hussain6d2a3322013-11-17 19:50:10 -080014355 hddLog(LOGE, FL("Called with Ie of length = %zu when not associated"),
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014356 ftie->ie_len);
Arif Hussain6d2a3322013-11-17 19:50:10 -080014357 hddLog(LOGE, FL("Should be Re-assoc Req IEs"));
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014358 }
14359
14360#ifdef WLAN_FEATURE_VOWIFI_11R_DEBUG
Arif Hussain6d2a3322013-11-17 19:50:10 -080014361 hddLog(LOGE, FL("%s called with Ie of length = %zu"), __func__,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014362 ftie->ie_len);
14363#endif
14364
14365 // Pass the received FT IEs to SME
Gopichand Nakkala356fb102013-03-06 12:34:04 +053014366 sme_SetFTIEs( WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
14367 (const u8 *)ftie->ie,
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014368 ftie->ie_len);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014369
14370 EXIT();
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014371 return 0;
14372}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053014373
14374static int wlan_hdd_cfg80211_update_ft_ies(struct wiphy *wiphy,
14375 struct net_device *dev,
14376 struct cfg80211_update_ft_ies_params *ftie)
14377{
14378 int ret;
14379
14380 vos_ssr_protect(__func__);
14381 ret = __wlan_hdd_cfg80211_update_ft_ies(wiphy, dev, ftie);
14382 vos_ssr_unprotect(__func__);
14383
14384 return ret;
14385}
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070014386#endif
Jeff Johnson04dd8a82012-06-29 20:41:40 -070014387
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014388#ifdef FEATURE_WLAN_SCAN_PNO
14389
14390void hdd_cfg80211_sched_scan_done_callback(void *callbackContext,
14391 tSirPrefNetworkFoundInd *pPrefNetworkFoundInd)
14392{
14393 int ret;
14394 hdd_adapter_t* pAdapter = (hdd_adapter_t*)callbackContext;
14395 hdd_context_t *pHddCtx;
14396
Nirav Shah80830bf2013-12-31 16:35:12 +053014397 ENTER();
14398
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014399 if (NULL == pAdapter)
14400 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053014401 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014402 "%s: HDD adapter is Null", __func__);
14403 return ;
14404 }
14405
14406 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14407 if (NULL == pHddCtx)
14408 {
14409 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14410 "%s: HDD context is Null!!!", __func__);
14411 return ;
14412 }
14413
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014414 spin_lock(&pHddCtx->schedScan_lock);
14415 if (TRUE == pHddCtx->isWiphySuspended)
14416 {
14417 pHddCtx->isSchedScanUpdatePending = TRUE;
14418 spin_unlock(&pHddCtx->schedScan_lock);
14419 hddLog(VOS_TRACE_LEVEL_INFO,
14420 "%s: Update cfg80211 scan database after it resume", __func__);
14421 return ;
14422 }
14423 spin_unlock(&pHddCtx->schedScan_lock);
14424
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014425 ret = wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter);
14426
14427 if (0 > ret)
14428 hddLog(VOS_TRACE_LEVEL_INFO, "%s: NO SCAN result", __func__);
14429
14430 cfg80211_sched_scan_results(pHddCtx->wiphy);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014431 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14432 "%s: cfg80211 scan result database updated", __func__);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014433}
14434
14435/*
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014436 * FUNCTION: wlan_hdd_is_pno_allowed
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014437 * Disallow pno if any session is active
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014438 */
14439static eHalStatus wlan_hdd_is_pno_allowed(hdd_adapter_t *pAdapter)
14440{
14441 hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
14442 hdd_adapter_t *pTempAdapter = NULL;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014443 hdd_station_ctx_t *pStaCtx;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014444 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14445 int status = 0;
14446 status = hdd_get_front_adapter(pHddCtx, &pAdapterNode);
14447
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014448 /* The current firmware design does not allow PNO during any
14449 * active sessions. Hence, determine the active sessions
14450 * and return a failure.
14451 */
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014452 while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == status))
14453 {
14454 pTempAdapter = pAdapterNode->pAdapter;
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014455 pStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pTempAdapter);
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014456
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014457 if (((WLAN_HDD_INFRA_STATION == pTempAdapter->device_mode)
14458 && (eConnectionState_NotConnected != pStaCtx->conn_info.connState))
14459 || (WLAN_HDD_P2P_CLIENT == pTempAdapter->device_mode)
14460 || (WLAN_HDD_P2P_GO == pTempAdapter->device_mode)
14461 || (WLAN_HDD_SOFTAP == pTempAdapter->device_mode)
Siddharth Bhal63a19a72014-11-07 14:31:56 +053014462 || (WLAN_HDD_TM_LEVEL_4 == pHddCtx->tmInfo.currentTmLevel)
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014463 )
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014464 {
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014465 return eHAL_STATUS_FAILURE;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014466 }
14467 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
14468 pAdapterNode = pNext;
14469 }
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014470 return eHAL_STATUS_SUCCESS;
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014471}
14472
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014473void hdd_cfg80211_sched_scan_start_status_cb(void *callbackContext, VOS_STATUS status)
14474{
14475 hdd_adapter_t *pAdapter = callbackContext;
14476 hdd_context_t *pHddCtx;
14477
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014478 ENTER();
14479
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014480 if ((NULL == pAdapter) || (WLAN_HDD_ADAPTER_MAGIC != pAdapter->magic))
14481 {
14482 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14483 FL("Invalid adapter or adapter has invalid magic"));
14484 return;
14485 }
14486
14487 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
14488 if (0 != wlan_hdd_validate_context(pHddCtx))
14489 {
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014490 return;
14491 }
14492
c_hpothub53c45d2014-08-18 16:53:14 +053014493 if (VOS_STATUS_SUCCESS != status)
14494 {
14495 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014496 FL("PNO enable response status = %d"), status);
c_hpothub53c45d2014-08-18 16:53:14 +053014497 pHddCtx->isPnoEnable = FALSE;
14498 }
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014499
14500 pAdapter->pno_req_status = (status == VOS_STATUS_SUCCESS) ? 0 : -EBUSY;
14501 complete(&pAdapter->pno_comp_var);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014502 EXIT();
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014503}
14504
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014505/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014506 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_start
14507 * Function to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014508 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014509static int __wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014510 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14511{
14512 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014513 tSirPNOScanReq pnoRequest = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014514 hdd_context_t *pHddCtx;
14515 tHalHandle hHal;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014516 v_U32_t i, indx, num_ch, tempInterval, j;
Sushant Kaushikd62d9782014-02-19 15:39:40 +053014517 u8 valid_ch[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
14518 u8 channels_allowed[WNI_CFG_VALID_CHANNEL_LIST_LEN] = {0};
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014519 v_U32_t num_channels_allowed = WNI_CFG_VALID_CHANNEL_LIST_LEN;
14520 eHalStatus status = eHAL_STATUS_FAILURE;
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014521 int ret = 0;
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014522 hdd_config_t *pConfig = NULL;
14523 v_U32_t num_ignore_dfs_ch = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014524
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014525 ENTER();
14526
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014527 if (NULL == pAdapter)
14528 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014529 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014530 "%s: HDD adapter is Null", __func__);
14531 return -ENODEV;
14532 }
14533
14534 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014535 ret = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014536
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014537 if (0 != ret)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014538 {
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014539 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014540 }
14541
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014542 pConfig = pHddCtx->cfg_ini;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014543 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14544 if (NULL == hHal)
14545 {
14546 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14547 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014548 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014549 }
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014550 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14551 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_START,
14552 pAdapter->sessionId, pAdapter->device_mode));
Sushant Kaushik2fe89932014-09-03 10:58:09 +053014553 sme_ScanFlushResult(hHal, pAdapter->sessionId);
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014554 ret = wlan_hdd_scan_abort(pAdapter);
Girish Gowli4bf7a632014-06-12 13:42:11 +053014555 if (ret < 0)
Mahesh A Saptasagar2395ee62014-05-21 19:12:21 +053014556 {
14557 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14558 "%s: aborting the existing scan is unsuccessfull", __func__);
14559 return -EBUSY;
14560 }
14561
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014562 if (eHAL_STATUS_SUCCESS != wlan_hdd_is_pno_allowed(pAdapter))
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014563 {
Vinay Krishna Erannacbf75f42014-02-26 17:35:20 +053014564 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Vinay Krishna Eranna23ffd182013-12-26 19:16:55 +053014565 FL("Cannot handle sched_scan"));
Mahesh A Saptasagar0f7b0372013-11-28 23:23:07 +053014566 return -EBUSY;
14567 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014568
c_hpothu37f21312014-04-09 21:49:54 +053014569 if (TRUE == pHddCtx->isPnoEnable)
14570 {
14571 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
14572 FL("already PNO is enabled"));
14573 return -EBUSY;
14574 }
c_hpothu225aa7c2014-10-22 17:45:13 +053014575
14576 if (VOS_STATUS_SUCCESS != wlan_hdd_cancel_remain_on_channel(pHddCtx))
14577 {
14578 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14579 "%s: abort ROC failed ", __func__);
14580 return -EBUSY;
14581 }
14582
c_hpothu37f21312014-04-09 21:49:54 +053014583 pHddCtx->isPnoEnable = TRUE;
14584
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014585 pnoRequest.enable = 1; /*Enable PNO */
14586 pnoRequest.ucNetworksCount = request->n_match_sets;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014587
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014588 if (( !pnoRequest.ucNetworksCount ) ||
14589 ( pnoRequest.ucNetworksCount > SIR_PNO_MAX_SUPP_NETWORKS ))
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014590 {
14591 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014592 "%s: Network input is not correct %d Max Network supported is %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014593 __func__, pnoRequest.ucNetworksCount,
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014594 SIR_PNO_MAX_SUPP_NETWORKS);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014595 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014596 goto error;
14597 }
14598
14599 if ( SIR_PNO_MAX_NETW_CHANNELS_EX < request->n_channels )
14600 {
14601 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014602 "%s: Incorrect number of channels %d",
14603 __func__, request->n_channels);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014604 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014605 goto error;
14606 }
14607
14608 /* Framework provides one set of channels(all)
14609 * common for all saved profile */
14610 if (0 != ccmCfgGetStr(hHal, WNI_CFG_VALID_CHANNEL_LIST,
14611 channels_allowed, &num_channels_allowed))
14612 {
14613 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14614 "%s: failed to get valid channel list", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014615 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014616 goto error;
14617 }
14618 /* Checking each channel against allowed channel list */
14619 num_ch = 0;
Nirav Shah80830bf2013-12-31 16:35:12 +053014620 if (request->n_channels)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014621 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014622 char chList [(request->n_channels*5)+1];
14623 int len;
14624 for (i = 0, len = 0; i < request->n_channels; i++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014625 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014626 for (indx = 0; indx < num_channels_allowed; indx++)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014627 {
Nirav Shah80830bf2013-12-31 16:35:12 +053014628 if (request->channels[i]->hw_value == channels_allowed[indx])
14629 {
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014630 if ((!pConfig->enableDFSPnoChnlScan) &&
14631 (NV_CHANNEL_DFS == vos_nv_getChannelEnabledState(channels_allowed[indx])))
14632 {
14633 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14634 "%s : Dropping DFS channel : %d",
14635 __func__,channels_allowed[indx]);
14636 num_ignore_dfs_ch++;
14637 break;
14638 }
14639
Nirav Shah80830bf2013-12-31 16:35:12 +053014640 valid_ch[num_ch++] = request->channels[i]->hw_value;
14641 len += snprintf(chList+len, 5, "%d ",
14642 request->channels[i]->hw_value);
14643 break ;
14644 }
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014645 }
14646 }
Nirav Shah80830bf2013-12-31 16:35:12 +053014647 hddLog(VOS_TRACE_LEVEL_INFO,"Channel-List: %s ", chList);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014648
Sachin Ahuja697ba3f2014-11-12 18:57:11 +053014649 /*If all channels are DFS and dropped, then ignore the PNO request*/
14650 if (num_ignore_dfs_ch == request->n_channels)
14651 {
14652 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14653 "%s : All requested channels are DFS channels", __func__);
14654 ret = -EINVAL;
14655 goto error;
14656 }
14657 }
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014658
14659 pnoRequest.aNetworks =
14660 vos_mem_malloc(sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14661 if (pnoRequest.aNetworks == NULL)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014662 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014663 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14664 FL("failed to allocate memory aNetworks %u"),
14665 (uint32)sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14666 goto error;
14667 }
14668 vos_mem_zero(pnoRequest.aNetworks,
14669 sizeof(tSirNetworkType)*pnoRequest.ucNetworksCount);
14670
14671 /* Filling per profile params */
14672 for (i = 0; i < pnoRequest.ucNetworksCount; i++)
14673 {
14674 pnoRequest.aNetworks[i].ssId.length =
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014675 request->match_sets[i].ssid.ssid_len;
14676
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014677 if (( 0 == pnoRequest.aNetworks[i].ssId.length ) ||
14678 ( pnoRequest.aNetworks[i].ssId.length > 32 ) )
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014679 {
14680 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014681 "%s: SSID Len %d is not correct for network %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014682 __func__, pnoRequest.aNetworks[i].ssId.length, i);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014683 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014684 goto error;
14685 }
14686
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014687 memcpy(pnoRequest.aNetworks[i].ssId.ssId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014688 request->match_sets[i].ssid.ssid,
14689 request->match_sets[i].ssid.ssid_len);
Sushant Kaushik1e406c32014-05-09 15:57:52 +053014690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14691 "%s: SSID of network %d is %s ", __func__,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014692 i, pnoRequest.aNetworks[i].ssId.ssId);
14693 pnoRequest.aNetworks[i].authentication = 0; /*eAUTH_TYPE_ANY*/
14694 pnoRequest.aNetworks[i].encryption = 0; /*eED_ANY*/
14695 pnoRequest.aNetworks[i].bcastNetwType = 0; /*eBCAST_UNKNOWN*/
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014696
14697 /*Copying list of valid channel into request */
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014698 memcpy(pnoRequest.aNetworks[i].aChannels, valid_ch, num_ch);
14699 pnoRequest.aNetworks[i].ucChannelCount = num_ch;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014700
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014701 pnoRequest.aNetworks[i].rssiThreshold = 0; //Default value
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014702 }
14703
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014704 for (i = 0; i < request->n_ssids; i++)
14705 {
14706 j = 0;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014707 while (j < pnoRequest.ucNetworksCount)
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014708 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014709 if ((pnoRequest.aNetworks[j].ssId.length ==
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014710 request->ssids[i].ssid_len) &&
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014711 (0 == memcmp(pnoRequest.aNetworks[j].ssId.ssId,
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014712 request->ssids[i].ssid,
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014713 pnoRequest.aNetworks[j].ssId.length)))
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014714 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014715 pnoRequest.aNetworks[j].bcastNetwType = eBCAST_HIDDEN;
Mahesh A Saptasagar7bd6ad42014-07-21 18:56:33 +053014716 break;
14717 }
14718 j++;
14719 }
14720 }
14721 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14722 "Number of hidden networks being Configured = %d",
14723 request->n_ssids);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014724 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Jeff Johnson59a121e2013-11-30 09:46:08 -080014725 "request->ie_len = %zu", request->ie_len);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014726
14727 pnoRequest.p24GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14728 if (pnoRequest.p24GProbeTemplate == NULL)
14729 {
14730 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14731 FL("failed to allocate memory p24GProbeTemplate %u"),
14732 SIR_PNO_MAX_PB_REQ_SIZE);
14733 goto error;
14734 }
14735
14736 pnoRequest.p5GProbeTemplate = vos_mem_malloc(SIR_PNO_MAX_PB_REQ_SIZE);
14737 if (pnoRequest.p5GProbeTemplate == NULL)
14738 {
14739 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR,
14740 FL("failed to allocate memory p5GProbeTemplate %u"),
14741 SIR_PNO_MAX_PB_REQ_SIZE);
14742 goto error;
14743 }
14744
14745 vos_mem_zero(pnoRequest.p24GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14746 vos_mem_zero(pnoRequest.p5GProbeTemplate, SIR_PNO_MAX_PB_REQ_SIZE);
14747
Hanumantha Reddy Pothula06e87b22015-03-02 18:02:23 +053014748 if ((0 < request->ie_len) && (request->ie_len <= SIR_PNO_MAX_PB_REQ_SIZE) &&
14749 (NULL != request->ie))
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014750 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014751 pnoRequest.us24GProbeTemplateLen = request->ie_len;
14752 memcpy(pnoRequest.p24GProbeTemplate, request->ie,
14753 pnoRequest.us24GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014754
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014755 pnoRequest.us5GProbeTemplateLen = request->ie_len;
14756 memcpy(pnoRequest.p5GProbeTemplate, request->ie,
14757 pnoRequest.us5GProbeTemplateLen);
Madan Mohan Koyyalamudia7765d52013-09-18 16:49:56 +053014758 }
14759
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014760 /* Driver gets only one time interval which is hardcoded in
14761 * supplicant for 10000ms. Taking power consumption into account 6 timers
14762 * will be used, Timervalue is increased exponentially i.e 10,20,40,
14763 * 80,160,320 secs. And number of scan cycle for each timer
14764 * is configurable through INI param gPNOScanTimerRepeatValue.
14765 * If it is set to 0 only one timer will be used and PNO scan cycle
14766 * will be repeated after each interval specified by supplicant
14767 * till PNO is disabled.
14768 */
14769 if (0 == pHddCtx->cfg_ini->configPNOScanTimerRepeatValue)
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014770 pnoRequest.scanTimers.ucScanTimersCount = HDD_PNO_SCAN_TIMERS_SET_ONE;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014771 else
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014772 pnoRequest.scanTimers.ucScanTimersCount =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014773 HDD_PNO_SCAN_TIMERS_SET_MULTIPLE;
14774
14775 tempInterval = (request->interval)/1000;
14776 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14777 "Base scan interval = %d PNOScanTimerRepeatValue = %d",
14778 tempInterval, pHddCtx->cfg_ini->configPNOScanTimerRepeatValue);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014779 for ( i = 0; i < pnoRequest.scanTimers.ucScanTimersCount; i++)
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014780 {
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014781 pnoRequest.scanTimers.aTimerValues[i].uTimerRepeat =
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014782 pHddCtx->cfg_ini->configPNOScanTimerRepeatValue;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014783 pnoRequest.scanTimers.aTimerValues[i].uTimerValue = tempInterval;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014784 tempInterval *= 2;
14785 }
14786 //Repeat last timer until pno disabled.
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014787 pnoRequest.scanTimers.aTimerValues[i-1].uTimerRepeat = 0;
Madan Mohan Koyyalamudi1d16f462013-08-27 16:25:34 +053014788
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014789 pnoRequest.modePNO = SIR_PNO_MODE_IMMEDIATE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014790
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014791 INIT_COMPLETION(pAdapter->pno_comp_var);
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014792 pnoRequest.statusCallback = hdd_cfg80211_sched_scan_start_status_cb;
14793 pnoRequest.callbackContext = pAdapter;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014794 pAdapter->pno_req_status = 0;
14795
Nirav Shah80830bf2013-12-31 16:35:12 +053014796 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14797 "SessionId %d, enable %d, modePNO %d, ucScanTimersCount %d",
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014798 pAdapter->sessionId, pnoRequest.enable, pnoRequest.modePNO,
14799 pnoRequest.scanTimers.ucScanTimersCount);
Nirav Shah80830bf2013-12-31 16:35:12 +053014800
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014801 status = sme_SetPreferredNetworkList(WLAN_HDD_GET_HAL_CTX(pAdapter),
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014802 &pnoRequest, pAdapter->sessionId,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014803 hdd_cfg80211_sched_scan_done_callback, pAdapter);
14804 if (eHAL_STATUS_SUCCESS != status)
14805 {
14806 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Nirav Shah80830bf2013-12-31 16:35:12 +053014807 "%s: Failed to enable PNO", __func__);
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014808 ret = -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014809 goto error;
14810 }
14811
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014812 ret = wait_for_completion_timeout(
14813 &pAdapter->pno_comp_var,
14814 msecs_to_jiffies(WLAN_WAIT_TIME_PNO));
14815 if (0 >= ret)
14816 {
14817 // Did not receive the response for PNO enable in time.
14818 // Assuming the PNO enable was success.
14819 // Returning error from here, because we timeout, results
14820 // in side effect of Wifi (Wifi Setting) not to work.
14821 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14822 FL("Timed out waiting for PNO to be Enabled"));
14823 ret = 0;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014824 }
14825
14826 ret = pAdapter->pno_req_status;
c_hpothu37f21312014-04-09 21:49:54 +053014827 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014828
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014829error:
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014830 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
14831 FL("PNO scanRequest offloaded ret = %d"), ret);
c_hpothu37f21312014-04-09 21:49:54 +053014832 pHddCtx->isPnoEnable = FALSE;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014833 if (pnoRequest.aNetworks)
14834 vos_mem_free(pnoRequest.aNetworks);
14835 if (pnoRequest.p24GProbeTemplate)
14836 vos_mem_free(pnoRequest.p24GProbeTemplate);
14837 if (pnoRequest.p5GProbeTemplate)
14838 vos_mem_free(pnoRequest.p5GProbeTemplate);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053014839
14840 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014841 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014842}
14843
14844/*
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014845 * FUNCTION: wlan_hdd_cfg80211_sched_scan_start
14846 * NL interface to enable PNO
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014847 */
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014848static int wlan_hdd_cfg80211_sched_scan_start(struct wiphy *wiphy,
14849 struct net_device *dev, struct cfg80211_sched_scan_request *request)
14850{
14851 int ret;
14852
14853 vos_ssr_protect(__func__);
14854 ret = __wlan_hdd_cfg80211_sched_scan_start(wiphy, dev, request);
14855 vos_ssr_unprotect(__func__);
14856
14857 return ret;
14858}
14859
14860/*
14861 * FUNCTION: __wlan_hdd_cfg80211_sched_scan_stop
14862 * Function to disable PNO
14863 */
14864static int __wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014865 struct net_device *dev)
14866{
14867 eHalStatus status = eHAL_STATUS_FAILURE;
14868 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
14869 hdd_context_t *pHddCtx;
14870 tHalHandle hHal;
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014871 tSirPNOScanReq pnoRequest = {0};
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014872 int ret = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014873
14874 ENTER();
14875
14876 if (NULL == pAdapter)
14877 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053014878 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014879 "%s: HDD adapter is Null", __func__);
14880 return -ENODEV;
14881 }
14882
14883 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014884
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014885 if (NULL == pHddCtx)
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014886 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053014887 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014888 "%s: HDD context is Null", __func__);
14889 return -ENODEV;
14890 }
14891
14892 /* The return 0 is intentional when isLogpInProgress and
14893 * isLoadUnloadInProgress. We did observe a crash due to a return of
14894 * failure in sched_scan_stop , especially for a case where the unload
14895 * of the happens at the same time. The function __cfg80211_stop_sched_scan
14896 * was clearing rdev->sched_scan_req only when the sched_scan_stop returns
14897 * success. If it returns a failure , then its next invocation due to the
14898 * clean up of the second interface will have the dev pointer corresponding
14899 * to the first one leading to a crash.
14900 */
14901 if (pHddCtx->isLogpInProgress)
14902 {
14903 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14904 "%s: LOGP in Progress. Ignore!!!", __func__);
14905 return ret;
14906 }
14907
Mihir Shete18156292014-03-11 15:38:30 +053014908 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014909 {
14910 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14911 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
14912 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014913 }
14914
14915 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
14916 if (NULL == hHal)
14917 {
14918 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14919 "%s: HAL context is Null!!!", __func__);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014920 return -EINVAL;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014921 }
14922
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014923 pnoRequest.enable = 0; /* Disable PNO */
14924 pnoRequest.ucNetworksCount = 0;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014925
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053014926 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
14927 TRACE_CODE_HDD_CFG80211_SCHED_SCAN_STOP,
14928 pAdapter->sessionId, pAdapter->device_mode));
Hanumantha Reddy Pothulad769f3e2015-02-19 17:00:02 +053014929 status = sme_SetPreferredNetworkList(hHal, &pnoRequest,
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014930 pAdapter->sessionId,
14931 NULL, pAdapter);
14932 if (eHAL_STATUS_SUCCESS != status)
14933 {
14934 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
14935 "Failed to disabled PNO");
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014936 ret = -EINVAL;
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014937 goto error;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014938 }
c_hpothu37f21312014-04-09 21:49:54 +053014939 pHddCtx->isPnoEnable = FALSE;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014940
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014941error:
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053014942 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Vinay Krishna Erannaf0e523b2014-03-01 21:00:16 +053014943 FL("PNO scan disabled ret = %d"), ret);
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014944
14945 EXIT();
Kamath Vinayakba5313f2013-08-22 15:52:39 +053014946 return ret;
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014947}
14948
Mahesh A Saptasagar6cc38562014-05-23 21:22:17 +053014949/*
14950 * FUNCTION: wlan_hdd_cfg80211_sched_scan_stop
14951 * NL interface to disable PNO
14952 */
14953static int wlan_hdd_cfg80211_sched_scan_stop(struct wiphy *wiphy,
14954 struct net_device *dev)
14955{
14956 int ret;
14957
14958 vos_ssr_protect(__func__);
14959 ret = __wlan_hdd_cfg80211_sched_scan_stop(wiphy, dev);
14960 vos_ssr_unprotect(__func__);
14961
14962 return ret;
14963}
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053014964#endif /*FEATURE_WLAN_SCAN_PNO*/
14965
14966
Mohit Khanna698ba2a2012-12-04 15:08:18 -080014967#ifdef FEATURE_WLAN_TDLS
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014968#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014969static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
14970 struct net_device *dev,
14971 u8 *peer, u8 action_code,
14972 u8 dialog_token,
14973 u16 status_code, u32 peer_capability,
14974 const u8 *buf, size_t len)
14975#else /* TDLS_MGMT_VERSION2 */
14976#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
14977static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
14978 struct net_device *dev,
14979 const u8 *peer, u8 action_code,
14980 u8 dialog_token, u16 status_code,
14981 u32 peer_capability, bool initiator,
14982 const u8 *buf, size_t len)
14983#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
14984static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
14985 struct net_device *dev,
14986 const u8 *peer, u8 action_code,
14987 u8 dialog_token, u16 status_code,
14988 u32 peer_capability, const u8 *buf,
14989 size_t len)
14990#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
14991static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
14992 struct net_device *dev,
14993 u8 *peer, u8 action_code,
14994 u8 dialog_token,
14995 u16 status_code, u32 peer_capability,
14996 const u8 *buf, size_t len)
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053014997#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053014998static int __wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
14999 struct net_device *dev,
15000 u8 *peer, u8 action_code,
15001 u8 dialog_token,
15002 u16 status_code, const u8 *buf,
15003 size_t len)
15004#endif
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015005#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015006{
15007
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015008 hdd_adapter_t *pAdapter;
15009 hdd_context_t *pHddCtx;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015010 VOS_STATUS status;
Gopichand Nakkala05922802013-03-14 12:23:19 -070015011 int max_sta_failed = 0;
Hoonki Leea34dd892013-02-05 22:56:02 -080015012 int responder;
Hoonki Leed37cbb32013-04-20 00:31:14 -070015013 long rc;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015014 int ret;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015015#if !(TDLS_MGMT_VERSION2) && (LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0))
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015016 u32 peer_capability = 0;
15017#endif
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015018 tANI_U16 numCurrTdlsPeers;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015019
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015020 pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15021 if (NULL == pAdapter)
15022 {
15023 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15024 "%s: Adapter is NULL",__func__);
15025 return -EINVAL;
15026 }
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015027 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15028 TRACE_CODE_HDD_CFG80211_TDLS_MGMT,
15029 pAdapter->sessionId, action_code));
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015030 pHddCtx = wiphy_priv(wiphy);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015031 if (NULL == pHddCtx || NULL == pHddCtx->cfg_ini)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015032 {
Gopichand Nakkala747461f2013-04-24 19:24:45 +053015033 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015034 "Invalid arguments");
15035 return -EINVAL;
15036 }
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015037 if (pHddCtx->isLogpInProgress)
15038 {
15039 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15040 "%s:LOGP in Progress. Ignore!!!", __func__);
Atul Mittal115287b2014-07-08 13:26:33 +053015041 wlan_hdd_tdls_set_link_status(pAdapter,
15042 peer,
15043 eTDLS_LINK_IDLE,
15044 eTDLS_LINK_UNSPECIFIED);
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015045 return -EBUSY;
15046 }
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053015047 if (WLAN_HDD_IS_LOAD_UNLOAD_IN_PROGRESS(pHddCtx))
15048 {
15049 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15050 "%s: Unloading/Loading in Progress. Ignore!!!", __func__);
15051 return -EAGAIN;
15052 }
Hoonki Lee27511902013-03-14 18:19:06 -070015053 if (eTDLS_SUPPORT_NOT_ENABLED == pHddCtx->tdls_mode)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015054 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015055 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015056 "%s: TDLS mode is disabled OR not enabled in FW."
15057 MAC_ADDRESS_STR " action %d declined.",
15058 __func__, MAC_ADDR_ARRAY(peer), action_code);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015059 return -ENOTSUPP;
15060 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015061
Hoonki Lee27511902013-03-14 18:19:06 -070015062 /* other than teardown frame, other mgmt frames are not sent if disabled */
15063 if (SIR_MAC_TDLS_TEARDOWN != action_code)
15064 {
15065 /* if tdls_mode is disabled to respond to peer's request */
15066 if (eTDLS_SUPPORT_DISABLED == pHddCtx->tdls_mode)
15067 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015068 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Hoonki Lee27511902013-03-14 18:19:06 -070015069 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015070 " TDLS mode is disabled. action %d declined.",
15071 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee27511902013-03-14 18:19:06 -070015072
15073 return -ENOTSUPP;
15074 }
Agarwal Ashish4b87f922014-06-18 03:03:21 +053015075
15076 if (vos_max_concurrent_connections_reached())
15077 {
15078 hddLog(VOS_TRACE_LEVEL_INFO, FL("Reached max concurrent connections"));
15079 return -EINVAL;
15080 }
Hoonki Lee27511902013-03-14 18:19:06 -070015081 }
15082
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015083 if (WLAN_IS_TDLS_SETUP_ACTION(action_code))
15084 {
Pradeep Reddy POTTETI9db32f02015-01-29 15:22:54 +053015085 if (NULL != wlan_hdd_tdls_is_progress(pHddCtx, peer, TRUE, TRUE))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015086 {
15087 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015088 "%s: " MAC_ADDRESS_STR
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015089 " TDLS setup is ongoing. action %d declined.",
15090 __func__, MAC_ADDR_ARRAY(peer), action_code);
15091 return -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015092 }
15093 }
15094
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015095 if (SIR_MAC_TDLS_SETUP_REQ == action_code ||
15096 SIR_MAC_TDLS_SETUP_RSP == action_code )
Lee Hoonkic1262f22013-01-24 21:59:00 -080015097 {
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015098 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15099 if (HDD_MAX_NUM_TDLS_STA <= numCurrTdlsPeers)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015100 {
15101 /* supplicant still sends tdls_mgmt(SETUP_REQ) even after
15102 we return error code at 'add_station()'. Hence we have this
15103 check again in addtion to add_station().
15104 Anyway, there is no hard to double-check. */
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015105 if (SIR_MAC_TDLS_SETUP_REQ == action_code)
Lee Hoonkic1262f22013-01-24 21:59:00 -080015106 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015107 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15108 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015109 " TDLS Max peer already connected. action (%d) declined. Num of peers (%d), Max allowed (%d).",
15110 __func__, MAC_ADDR_ARRAY(peer), action_code,
15111 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Sunil Dutt388ac8f2013-11-28 18:06:52 +053015112 return -EINVAL;
Lee Hoonkic1262f22013-01-24 21:59:00 -080015113 }
15114 else
15115 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015116 /* maximum reached. tweak to send error code to peer and return
15117 error code to supplicant */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015118 status_code = eSIR_MAC_UNSPEC_FAILURE_STATUS;
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015119 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15120 "%s: " MAC_ADDRESS_STR
Rajesh Chauhana34c6e62014-03-25 16:37:58 +053015121 " TDLS Max peer already connected, send response status (%d). Num of peers (%d), Max allowed (%d).",
15122 __func__, MAC_ADDR_ARRAY(peer), status_code,
15123 numCurrTdlsPeers, HDD_MAX_NUM_TDLS_STA);
Gopichand Nakkala05922802013-03-14 12:23:19 -070015124 max_sta_failed = -EPERM;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015125 /* fall through to send setup resp with failure status
15126 code */
Lee Hoonkic1262f22013-01-24 21:59:00 -080015127 }
15128 }
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015129 else
15130 {
15131 hddTdlsPeer_t *pTdlsPeer;
Madan Mohan Koyyalamudi96797442013-10-08 16:04:42 +053015132 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015133 if (pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015134 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015135 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala34d1b062013-03-19 15:28:33 -070015136 "%s:" MAC_ADDRESS_STR " already connected. action %d declined.",
15137 __func__, MAC_ADDR_ARRAY(peer), action_code);
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015138 return -EPERM;
15139 }
15140 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015141 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015142
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015143 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015144 "%s: " MAC_ADDRESS_STR " action %d, dialog_token %d status %d, len = %zu",
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015145 "tdls_mgmt", MAC_ADDR_ARRAY(peer),
15146 action_code, dialog_token, status_code, len);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015147
Hoonki Leea34dd892013-02-05 22:56:02 -080015148 /*Except teardown responder will not be used so just make 0*/
15149 responder = 0;
Hoonki Lee11f7dda2013-02-14 16:55:44 -080015150 if (SIR_MAC_TDLS_TEARDOWN == action_code)
Hoonki Leea34dd892013-02-05 22:56:02 -080015151 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015152
15153 hddTdlsPeer_t *pTdlsPeer;
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015154 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015155
15156 if(pTdlsPeer && TDLS_IS_CONNECTED(pTdlsPeer))
15157 responder = pTdlsPeer->is_responder;
15158 else
Hoonki Leea34dd892013-02-05 22:56:02 -080015159 {
Gopichand Nakkala97a65fd2013-04-16 16:59:38 -070015160 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arun Kumar Khandavalli9fb625e2014-03-17 16:07:40 +053015161 "%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 -070015162 __func__, MAC_ADDR_ARRAY(peer), (NULL == pTdlsPeer) ? -1 : pTdlsPeer->link_status,
15163 dialog_token, status_code, len);
15164 return -EPERM;
Hoonki Leea34dd892013-02-05 22:56:02 -080015165 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015166 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015167
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015168 /* For explicit trigger of DIS_REQ come out of BMPS for
15169 successfully receiving DIS_RSP from peer. */
Hoonki Lee14621352013-04-16 17:51:19 -070015170 if ((SIR_MAC_TDLS_SETUP_RSP == action_code) ||
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015171 (SIR_MAC_TDLS_DIS_RSP == action_code) ||
15172 (SIR_MAC_TDLS_DIS_REQ == action_code))
Hoonki Lee14621352013-04-16 17:51:19 -070015173 {
15174 if (TRUE == sme_IsPmcBmps(WLAN_HDD_GET_HAL_CTX(pAdapter)))
15175 {
Masti, Narayanraddi34e0e562015-03-05 18:23:03 +053015176 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Gopichand Nakkala2f1ff152013-07-01 11:27:43 +053015177 "%s: Sending frame action_code %u.Disable BMPS", __func__, action_code);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015178 status = hdd_disable_bmps_imps(pHddCtx, WLAN_HDD_INFRA_STATION);
15179 if (status != VOS_STATUS_SUCCESS) {
15180 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set BMPS/IMPS"));
15181 }
Hoonki Lee14621352013-04-16 17:51:19 -070015182 }
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015183 if (SIR_MAC_TDLS_DIS_REQ != action_code) {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015184 if (0 != wlan_hdd_tdls_set_cap(pAdapter, peer, eTDLS_CAP_SUPPORTED)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015185 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS capabilities"));
15186 }
15187 }
Hoonki Lee14621352013-04-16 17:51:19 -070015188 }
15189
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015190 /* make sure doesn't call send_mgmt() while it is pending */
15191 if (TDLS_CTX_MAGIC == pAdapter->mgmtTxCompletionStatus)
15192 {
15193 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Arif Hussain6d2a3322013-11-17 19:50:10 -080015194 "%s: " MAC_ADDRESS_STR " action %d couldn't sent, as one is pending. return EBUSY",
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015195 __func__, MAC_ADDR_ARRAY(peer), action_code);
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015196 ret = -EBUSY;
15197 goto tx_failed;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015198 }
15199
15200 pAdapter->mgmtTxCompletionStatus = TDLS_CTX_MAGIC;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015201 INIT_COMPLETION(pAdapter->tdls_mgmt_comp);
15202
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015203 status = sme_SendTdlsMgmtFrame(WLAN_HDD_GET_HAL_CTX(pAdapter), pAdapter->sessionId,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015204 peer, action_code, dialog_token, status_code, peer_capability, (tANI_U8 *)buf, len, responder);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015205
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015206 if (VOS_STATUS_SUCCESS != status)
15207 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015208 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15209 "%s: sme_SendTdlsMgmtFrame failed!", __func__);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015210 pAdapter->mgmtTxCompletionStatus = FALSE;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015211 ret = -EINVAL;
15212 goto tx_failed;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015213 }
15214
Hoonki Leed37cbb32013-04-20 00:31:14 -070015215 rc = wait_for_completion_interruptible_timeout(&pAdapter->tdls_mgmt_comp,
15216 msecs_to_jiffies(WAIT_TIME_TDLS_MGMT));
15217
15218 if ((rc <= 0) || (TRUE != pAdapter->mgmtTxCompletionStatus))
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015219 {
Hoonki Leed37cbb32013-04-20 00:31:14 -070015220 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Jeff Johnson0299d0a2013-10-30 12:37:43 -070015221 "%s: Mgmt Tx Completion failed status %ld TxCompletion %u",
Hoonki Leed37cbb32013-04-20 00:31:14 -070015222 __func__, rc, pAdapter->mgmtTxCompletionStatus);
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015223 pAdapter->mgmtTxCompletionStatus = FALSE;
Yue Ma4f55ef32014-01-23 16:45:33 -080015224
15225 if (pHddCtx->isLogpInProgress)
15226 {
15227 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15228 "%s: LOGP in Progress. Ignore!!!", __func__);
15229 return -EAGAIN;
15230 }
15231
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015232 ret = -EINVAL;
15233 goto tx_failed;
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015234 }
15235
Gopichand Nakkala05922802013-03-14 12:23:19 -070015236 if (max_sta_failed)
Hoonki Lee14621352013-04-16 17:51:19 -070015237 {
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015238 ret = max_sta_failed;
15239 goto tx_failed;
Hoonki Lee14621352013-04-16 17:51:19 -070015240 }
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015241
Hoonki Leea34dd892013-02-05 22:56:02 -080015242 if (SIR_MAC_TDLS_SETUP_RSP == action_code)
15243 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015244 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, TRUE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015245 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15246 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015247 }
15248 else if (SIR_MAC_TDLS_SETUP_CNF == action_code)
15249 {
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015250 if (0 != wlan_hdd_tdls_set_responder(pAdapter, peer, FALSE)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015251 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set TDLS responder: Setup Response"));
15252 }
Hoonki Leea34dd892013-02-05 22:56:02 -080015253 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015254
15255 return 0;
Ganesh Kondabattini862aec92015-01-22 20:58:46 +053015256
15257tx_failed:
15258 /* add_station will be called before sending TDLS_SETUP_REQ and
15259 * TDLS_SETUP_RSP and as part of add_station driver will enable
15260 * BMPS. NL80211_TDLS_DISABLE_LINK will be called if the tx of
15261 * TDLS_SETUP_REQ or TDLS_SETUP_RSP fails. BMPS will be enabled
15262 * as part of processing NL80211_TDLS_DISABLE_LINK. So need to
15263 * enable BMPS for TDLS_SETUP_REQ and TDLS_SETUP_RSP if tx fails.
15264 */
15265
15266 if ((SIR_MAC_TDLS_SETUP_REQ == action_code) ||
15267 (SIR_MAC_TDLS_SETUP_RSP == action_code))
15268 wlan_hdd_tdls_check_bmps(pAdapter);
15269 return ret;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015270}
15271
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015272#if TDLS_MGMT_VERSION2
15273static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15274 u8 *peer, u8 action_code, u8 dialog_token,
15275 u16 status_code, u32 peer_capability,
15276 const u8 *buf, size_t len)
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015277#else /* TDLS_MGMT_VERSION2 */
15278#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
15279static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15280 struct net_device *dev,
15281 const u8 *peer, u8 action_code,
15282 u8 dialog_token, u16 status_code,
15283 u32 peer_capability, bool initiator,
15284 const u8 *buf, size_t len)
15285#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15286static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15287 struct net_device *dev,
15288 const u8 *peer, u8 action_code,
15289 u8 dialog_token, u16 status_code,
15290 u32 peer_capability, const u8 *buf,
15291 size_t len)
15292#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
15293static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy,
15294 struct net_device *dev,
15295 u8 *peer, u8 action_code,
15296 u8 dialog_token,
15297 u16 status_code, u32 peer_capability,
15298 const u8 *buf, size_t len)
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015299#else
15300static int wlan_hdd_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
15301 u8 *peer, u8 action_code, u8 dialog_token,
15302 u16 status_code, const u8 *buf, size_t len)
15303#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015304#endif
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015305{
15306 int ret;
15307
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015308 vos_ssr_protect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015309#if TDLS_MGMT_VERSION2
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015310 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15311 dialog_token, status_code,
15312 peer_capability, buf, len);
15313#else /* TDLS_MGMT_VERSION2 */
15314#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0)) || defined(WITH_BACKPORTS)
15315 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15316 dialog_token, status_code,
15317 peer_capability, initiator,
15318 buf, len);
15319#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
15320 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15321 dialog_token, status_code,
15322 peer_capability, buf, len);
15323#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
15324 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15325 dialog_token, status_code,
15326 peer_capability, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015327#else
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015328 ret = __wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer, action_code,
15329 dialog_token, status_code, buf, len);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015330#endif
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015331#endif
15332 vos_ssr_unprotect(__func__);
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015333
Anand N Sunkad9f80b742015-07-30 20:05:51 +053015334 return ret;
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053015335}
Atul Mittal115287b2014-07-08 13:26:33 +053015336
15337int wlan_hdd_tdls_extctrl_config_peer(hdd_adapter_t *pAdapter,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015338#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15339 const u8 *peer,
15340#else
Atul Mittal115287b2014-07-08 13:26:33 +053015341 u8 *peer,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015342#endif
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015343 tdls_req_params_t *tdls_peer_params,
Atul Mittal115287b2014-07-08 13:26:33 +053015344 cfg80211_exttdls_callback callback)
15345{
15346
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015347 hddTdlsPeer_t *pTdlsPeer = NULL;
Atul Mittal115287b2014-07-08 13:26:33 +053015348 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015349 hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
Atul Mittal115287b2014-07-08 13:26:33 +053015350 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15351 " %s : NL80211_TDLS_SETUP for " MAC_ADDRESS_STR,
15352 __func__, MAC_ADDR_ARRAY(peer));
15353
15354 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
15355 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
15356
15357 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015358 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
15359 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
15360 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053015361 return -ENOTSUPP;
15362 }
15363
15364 /* To cater the requirement of establishing the TDLS link
15365 * irrespective of the data traffic , get an entry of TDLS peer.
15366 */
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015367 mutex_lock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015368 pTdlsPeer = wlan_hdd_tdls_get_peer(pAdapter, peer);
15369 if (pTdlsPeer == NULL) {
15370 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15371 "%s: peer " MAC_ADDRESS_STR " not existing",
15372 __func__, MAC_ADDR_ARRAY(peer));
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015373 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015374 return -EINVAL;
15375 }
Masti, Narayanraddi6dbcdbb2015-05-13 10:28:06 +053015376 mutex_unlock(&pHddCtx->tdls_lock);
Atul Mittal115287b2014-07-08 13:26:33 +053015377
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053015378 /* check FW TDLS Off Channel capability */
15379 if ((TRUE == sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL)) &&
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053015380 (TRUE == pHddCtx->cfg_ini->fEnableTDLSOffChannel) &&
Pradeep Reddy POTTETI60ad2402015-02-26 16:48:21 +053015381 (NULL != tdls_peer_params))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015382 {
15383 pTdlsPeer->peerParams.channel = tdls_peer_params->channel;
15384 pTdlsPeer->peerParams.global_operating_class =
15385 tdls_peer_params->global_operating_class;
15386 pTdlsPeer->peerParams.max_latency_ms = tdls_peer_params->max_latency_ms;
15387 pTdlsPeer->peerParams.min_bandwidth_kbps =
15388 tdls_peer_params->min_bandwidth_kbps;
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015389 /* check configured channel is valid, non dfs and
15390 * not current operating channel */
15391 if ((sme_IsTdlsOffChannelValid(WLAN_HDD_GET_HAL_CTX(pAdapter),
15392 tdls_peer_params->channel)) &&
15393 (pHddStaCtx) &&
15394 (tdls_peer_params->channel !=
15395 pHddStaCtx->conn_info.operationChannel))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015396 {
15397 pTdlsPeer->isOffChannelConfigured = TRUE;
15398 }
15399 else
15400 {
15401 pTdlsPeer->isOffChannelConfigured = FALSE;
15402 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15403 "%s: Configured Tdls Off Channel is not valid", __func__);
15404
15405 }
15406 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015407 "%s: tdls_off_channel %d isOffChannelConfigured %d "
15408 "current operating channel %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015409 __func__, pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIe30ed252015-02-18 14:27:55 +053015410 pTdlsPeer->isOffChannelConfigured,
15411 (pHddStaCtx ? pHddStaCtx->conn_info.operationChannel : 0));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015412 }
15413 else
15414 {
15415 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Pradeep Reddy POTTETI0cb99bc2015-06-08 12:59:09 +053015416 "%s: TDLS off channel FW capability %d, "
15417 "host capab %d or Invalid TDLS Peer Params", __func__,
15418 sme_IsFeatureSupportedByFW(TDLS_OFF_CHANNEL),
15419 pHddCtx->cfg_ini->fEnableTDLSOffChannel);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015420 }
15421
Atul Mittal115287b2014-07-08 13:26:33 +053015422 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, TRUE) ) {
15423
15424 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15425 " %s TDLS Add Force Peer Failed",
15426 __func__);
15427 return -EINVAL;
15428 }
15429 /*EXT TDLS*/
15430
15431 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, callback) ) {
15432 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15433 " %s TDLS set callback Failed",
15434 __func__);
15435 return -EINVAL;
15436 }
15437
15438 return(0);
15439
15440}
15441
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015442int wlan_hdd_tdls_extctrl_deconfig_peer(hdd_adapter_t *pAdapter,
15443#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15444 const u8 *peer
15445#else
15446 u8 *peer
15447#endif
15448)
Atul Mittal115287b2014-07-08 13:26:33 +053015449{
15450
15451 hddTdlsPeer_t *pTdlsPeer;
15452 hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
15453 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15454 " %s : NL80211_TDLS_TEARDOWN for " MAC_ADDRESS_STR,
15455 __func__, MAC_ADDR_ARRAY(peer));
15456
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015457 if (0 != wlan_hdd_validate_context(pHddCtx)) {
15458 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD context is NULL"));
15459 return -EINVAL;
15460 }
15461
Atul Mittal115287b2014-07-08 13:26:33 +053015462 if ( (FALSE == pHddCtx->cfg_ini->fTDLSExternalControl) ||
15463 (FALSE == pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger) ) {
15464
15465 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015466 " %s TDLS External control (%d) and Implicit Trigger (%d) not enabled ",
15467 __func__, pHddCtx->cfg_ini->fTDLSExternalControl,
15468 pHddCtx->cfg_ini->fEnableTDLSImplicitTrigger);
Atul Mittal115287b2014-07-08 13:26:33 +053015469 return -ENOTSUPP;
15470 }
15471
15472
15473 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15474
15475 if ( NULL == pTdlsPeer ) {
15476 hddLog(VOS_TRACE_LEVEL_INFO, "%s: " MAC_ADDRESS_STR
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015477 " peer not existing",
Atul Mittal115287b2014-07-08 13:26:33 +053015478 __func__, MAC_ADDR_ARRAY(peer));
15479 return -EINVAL;
15480 }
15481 else {
15482 wlan_hdd_tdls_indicate_teardown(pAdapter, pTdlsPeer,
15483 eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON);
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015484 /* if channel switch is configured, reset
15485 the channel for this peer */
15486 if (TRUE == pTdlsPeer->isOffChannelConfigured)
15487 {
15488 pTdlsPeer->peerParams.channel = 0;
15489 pTdlsPeer->isOffChannelConfigured = FALSE;
15490 }
Atul Mittal115287b2014-07-08 13:26:33 +053015491 }
15492
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015493 if ( 0 != wlan_hdd_tdls_set_force_peer(pAdapter, peer, FALSE) ) {
15494 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to set force peer"));
Atul Mittal115287b2014-07-08 13:26:33 +053015495 return -EINVAL;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015496 }
Atul Mittal115287b2014-07-08 13:26:33 +053015497
15498 /*EXT TDLS*/
15499
15500 if ( 0 != wlan_hdd_set_callback(pTdlsPeer, NULL )) {
15501
15502 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15503 " %s TDLS set callback Failed",
15504 __func__);
15505 return -EINVAL;
15506 }
15507 return(0);
15508
15509}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015510static int __wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015511#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15512 const u8 *peer,
15513#else
15514 u8 *peer,
15515#endif
15516 enum nl80211_tdls_operation oper)
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015517{
15518 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
15519 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015520 int status;
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015521 hddTdlsPeer_t *pTdlsPeer;
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053015522
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015523 ENTER();
15524
Chandrasekaran, Manishekar41b8e1f2015-03-10 13:30:28 +053015525 if (!pAdapter) {
15526 hddLog(VOS_TRACE_LEVEL_ERROR, FL("HDD adpater is NULL"));
15527 return -EINVAL;
15528 }
15529
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053015530 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
15531 TRACE_CODE_HDD_CFG80211_TDLS_OPER,
15532 pAdapter->sessionId, oper));
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015533 if ( NULL == peer )
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015534 {
Gopichand Nakkalab977a972013-02-18 19:15:09 -080015535 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chilam Ngc4244af2013-04-01 15:37:32 -070015536 "%s: Invalid arguments", __func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015537 return -EINVAL;
15538 }
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015539
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015540 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015541 if (0 != status)
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015542 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053015543 return status;
Sameer Thalappil75ea31a2013-02-21 19:38:16 -080015544 }
15545
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015546
15547 if( FALSE == pHddCtx->cfg_ini->fEnableTDLSSupport ||
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015548 FALSE == sme_IsFeatureSupportedByFW(TDLS))
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015549 {
Hoonki Lee1090c6a2013-01-16 17:40:54 -080015550 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015551 "TDLS Disabled in INI (%d) OR not enabled in FW (%d) "
15552 "Cannot process TDLS commands",
15553 pHddCtx->cfg_ini->fEnableTDLSSupport,
15554 sme_IsFeatureSupportedByFW(TDLS));
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015555 return -ENOTSUPP;
15556 }
15557
15558 switch (oper) {
15559 case NL80211_TDLS_ENABLE_LINK:
15560 {
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015561 VOS_STATUS status;
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015562 long ret;
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015563 tCsrTdlsLinkEstablishParams tdlsLinkEstablishParams;
Agarwal Ashish16020c42014-12-29 22:01:11 +053015564 WLAN_STADescType staDesc;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015565 tANI_U16 numCurrTdlsPeers = 0;
15566 hddTdlsPeer_t *connPeer = NULL;
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015567 tANI_U8 suppChannelLen = 0;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015568
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015569 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15570 " %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
15571 __func__, MAC_ADDR_ARRAY(peer));
Sunil Dutt41de4e22013-11-14 18:09:02 +053015572 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
Agarwal Ashish16020c42014-12-29 22:01:11 +053015573 memset(&staDesc, 0, sizeof(staDesc));
Sunil Dutt41de4e22013-11-14 18:09:02 +053015574 if ( NULL == pTdlsPeer ) {
15575 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15576 " (oper %d) not exsting. ignored",
15577 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15578 return -EINVAL;
15579 }
15580
15581 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15582 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15583 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15584 "NL80211_TDLS_ENABLE_LINK");
15585
Gopichand Nakkala2f4a2822013-04-17 11:22:01 -070015586 if (!TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
15587 {
15588 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
15589 MAC_ADDRESS_STR " failed",
15590 __func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
15591 return -EINVAL;
15592 }
15593
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053015594 /* before starting tdls connection, set tdls
15595 * off channel established status to default value */
15596 pTdlsPeer->isOffChannelEstablished = FALSE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015597 /* TDLS Off Channel, Disable tdls channel switch,
15598 when there are more than one tdls link */
15599 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
Pradeep Reddy POTTETIa9991b62015-03-26 18:03:19 +053015600 if (numCurrTdlsPeers == 2)
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015601 {
15602 /* get connected peer and send disable tdls off chan */
15603 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015604 if ((connPeer) &&
15605 (connPeer->isOffChannelSupported == TRUE) &&
15606 (connPeer->isOffChannelConfigured == TRUE))
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015607 {
15608 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15609 "%s: More then one peer connected, Disable "
15610 "TDLS channel switch", __func__);
15611
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015612 connPeer->isOffChannelEstablished = FALSE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015613 ret = sme_SendTdlsChanSwitchReq(
15614 WLAN_HDD_GET_HAL_CTX(pAdapter),
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015615 pAdapter->sessionId,
15616 connPeer->peerMac,
15617 connPeer->peerParams.channel,
15618 TDLS_OFF_CHANNEL_BW_OFFSET,
15619 TDLS_CHANNEL_SWITCH_DISABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015620 if (ret != VOS_STATUS_SUCCESS) {
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015621 hddLog(VOS_TRACE_LEVEL_ERROR,
15622 FL("Failed to send TDLS switch channel request"));
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015623 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015624 }
15625 else
15626 {
15627 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15628 "%s: No TDLS Connected Peer or "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015629 "isOffChannelSupported %d "
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015630 "isOffChannelConfigured %d",
15631 __func__,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015632 (connPeer ? (connPeer->isOffChannelSupported)
15633 : -1),
15634 (connPeer ? (connPeer->isOffChannelConfigured)
15635 : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015636 }
15637 }
15638
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015639 if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015640 {
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015641 if (IS_ADVANCE_TDLS_ENABLE) {
Gopichand Nakkala24be5312013-07-02 16:47:12 +053015642
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015643 if (0 != wlan_hdd_tdls_get_link_establish_params(
15644 pAdapter, peer,&tdlsLinkEstablishParams)) {
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015645 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to get link establishment params"));
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015646 return -EINVAL;
15647 }
15648 INIT_COMPLETION(pAdapter->tdls_link_establish_req_comp);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015649
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015650 ret = sme_SendTdlsLinkEstablishParams(
15651 WLAN_HDD_GET_HAL_CTX(pAdapter),
15652 pAdapter->sessionId, peer,
15653 &tdlsLinkEstablishParams);
15654 if (ret != VOS_STATUS_SUCCESS) {
15655 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send link establishment params"));
15656 }
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015657 /* Send TDLS peer UAPSD capabilities to the firmware and
15658 * register with the TL on after the response for this operation
15659 * is received .
15660 */
15661 ret = wait_for_completion_interruptible_timeout(
15662 &pAdapter->tdls_link_establish_req_comp,
15663 msecs_to_jiffies(WAIT_TIME_TDLS_LINK_ESTABLISH_REQ));
15664 if (ret <= 0)
15665 {
15666 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015667 FL("Link Establish Request Failed Status %ld"),
15668 ret);
Madan Mohan Koyyalamudice419872013-09-13 19:36:52 +053015669 return -EINVAL;
15670 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015671 }
Atul Mittal115287b2014-07-08 13:26:33 +053015672 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15673 eTDLS_LINK_CONNECTED,
15674 eTDLS_LINK_SUCCESS);
Agarwal Ashish16020c42014-12-29 22:01:11 +053015675 staDesc.ucSTAId = pTdlsPeer->staId;
15676 staDesc.ucQosEnabled = tdlsLinkEstablishParams.qos;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015677 ret = WLANTL_UpdateTdlsSTAClient(
15678 pHddCtx->pvosContext,
15679 &staDesc);
15680 if (ret != VOS_STATUS_SUCCESS) {
15681 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to update TDLS STA params"));
15682 }
Agarwal Ashish16020c42014-12-29 22:01:11 +053015683
Gopichand Nakkala471708b2013-06-04 20:03:01 +053015684 /* Mark TDLS client Authenticated .*/
15685 status = WLANTL_ChangeSTAState( pHddCtx->pvosContext,
15686 pTdlsPeer->staId,
15687 WLANTL_STA_AUTHENTICATED);
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015688 if (VOS_STATUS_SUCCESS == status)
15689 {
Hoonki Lee14621352013-04-16 17:51:19 -070015690 if (pTdlsPeer->is_responder == 0)
15691 {
15692 v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
15693
15694 wlan_hdd_tdls_timer_restart(pAdapter,
15695 &pTdlsPeer->initiatorWaitTimeoutTimer,
15696 WAIT_TIME_TDLS_INITIATOR);
15697 /* suspend initiator TX until it receives direct packet from the
15698 reponder or WAIT_TIME_TDLS_INITIATOR timer expires */
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015699 ret = WLANTL_SuspendDataTx(
15700 (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15701 &staId, NULL);
15702 if (ret != VOS_STATUS_SUCCESS) {
15703 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to suspend data tx"));
15704 }
Hoonki Lee14621352013-04-16 17:51:19 -070015705 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015706
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015707 if ((TRUE == pTdlsPeer->isOffChannelSupported) &&
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015708 (TRUE == pTdlsPeer->isOffChannelConfigured))
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015709 {
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015710 suppChannelLen =
15711 tdlsLinkEstablishParams.supportedChannelsLen;
15712
15713 if ((suppChannelLen > 0) &&
15714 (suppChannelLen <= SIR_MAC_MAX_SUPP_CHANNELS))
15715 {
15716 tANI_U8 suppPeerChannel = 0;
15717 int i = 0;
15718 for (i = 0U; i < suppChannelLen; i++)
15719 {
15720 suppPeerChannel =
15721 tdlsLinkEstablishParams.supportedChannels[i];
15722
15723 pTdlsPeer->isOffChannelSupported = FALSE;
15724 if (suppPeerChannel ==
15725 pTdlsPeer->peerParams.channel)
15726 {
15727 pTdlsPeer->isOffChannelSupported = TRUE;
15728 break;
15729 }
15730 }
15731 }
15732 else
15733 {
15734 pTdlsPeer->isOffChannelSupported = FALSE;
15735 }
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015736 }
15737 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15738 "%s: TDLS channel switch request for channel "
15739 "%d isOffChannelConfigured %d suppChannelLen "
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015740 "%d isOffChannelSupported %d", __func__,
15741 pTdlsPeer->peerParams.channel,
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015742 pTdlsPeer->isOffChannelConfigured,
Pradeep Reddy POTTETIfdaf38b2015-05-13 13:01:22 +053015743 suppChannelLen,
15744 pTdlsPeer->isOffChannelSupported);
Pradeep Reddy POTTETIfcac7902015-04-16 12:25:17 +053015745
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015746 /* TDLS Off Channel, Enable tdls channel switch,
15747 when their is only one tdls link and it supports */
15748 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15749 if ((numCurrTdlsPeers == 1) &&
15750 (TRUE == pTdlsPeer->isOffChannelSupported) &&
15751 (TRUE == pTdlsPeer->isOffChannelConfigured))
15752 {
15753 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15754 "%s: Send TDLS channel switch request for channel %d",
15755 __func__, pTdlsPeer->peerParams.channel);
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015756
15757 pTdlsPeer->isOffChannelEstablished = TRUE;
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015758 ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
15759 pAdapter->sessionId,
15760 pTdlsPeer->peerMac,
15761 pTdlsPeer->peerParams.channel,
15762 TDLS_OFF_CHANNEL_BW_OFFSET,
15763 TDLS_CHANNEL_SWITCH_ENABLE);
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015764 if (ret != VOS_STATUS_SUCCESS) {
15765 hddLog(VOS_TRACE_LEVEL_ERROR, FL("TDLS offchannel: Failed to send TDLS switch channel req"));
15766 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015767 }
15768 else
15769 {
15770 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15771 "%s: TDLS channel switch request not sent"
15772 " numCurrTdlsPeers %d "
15773 "isOffChannelSupported %d "
15774 "isOffChannelConfigured %d",
15775 __func__, numCurrTdlsPeers,
15776 pTdlsPeer->isOffChannelSupported,
15777 pTdlsPeer->isOffChannelConfigured);
15778 }
15779
Gopichand Nakkalaccd3a382013-03-19 13:56:10 -070015780 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015781 wlan_hdd_tdls_check_bmps(pAdapter);
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015782
15783 /* Update TL about the UAPSD masks , to route the packets to firmware */
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015784 if ((TRUE == pHddCtx->cfg_ini->fEnableTDLSBufferSta)
15785 || pHddCtx->cfg_ini->fTDLSUapsdMask )
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015786 {
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015787 int ac;
15788 uint8 ucAc[4] = { WLANTL_AC_VO,
15789 WLANTL_AC_VI,
15790 WLANTL_AC_BK,
15791 WLANTL_AC_BE };
15792 uint8 tlTid[4] = { 7, 5, 2, 3 } ;
15793 for(ac=0; ac < 4; ac++)
15794 {
15795 status = WLANTL_EnableUAPSDForAC( (WLAN_HDD_GET_CTX(pAdapter))->pvosContext,
15796 pTdlsPeer->staId, ucAc[ac],
15797 tlTid[ac], tlTid[ac], 0, 0,
15798 WLANTL_BI_DIR );
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015799 if (status != VOS_STATUS_SUCCESS) {
15800 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to enable UAPSD for AC"));
15801 }
Gopichand Nakkala574f6d12013-06-27 19:38:43 +053015802 }
Gopichand Nakkala79ff85d2013-05-27 17:05:29 +053015803 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015804 }
15805
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015806 }
15807 break;
15808 case NL80211_TDLS_DISABLE_LINK:
Lee Hoonkic1262f22013-01-24 21:59:00 -080015809 {
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015810 tANI_U16 numCurrTdlsPeers = 0;
15811 hddTdlsPeer_t *connPeer = NULL;
15812
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015813 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15814 " %s : NL80211_TDLS_DISABLE_LINK for " MAC_ADDRESS_STR,
15815 __func__, MAC_ADDR_ARRAY(peer));
15816
Sunil Dutt41de4e22013-11-14 18:09:02 +053015817 pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
15818
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015819
Sunil Dutt41de4e22013-11-14 18:09:02 +053015820 if ( NULL == pTdlsPeer ) {
15821 hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
15822 " (oper %d) not exsting. ignored",
15823 __func__, MAC_ADDR_ARRAY(peer), (int)oper);
15824 return -EINVAL;
15825 }
15826
15827 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15828 "%s: " MAC_ADDRESS_STR " link_status %d (%s) ", "tdls_oper",
15829 MAC_ADDR_ARRAY(peer), pTdlsPeer->link_status,
15830 "NL80211_TDLS_DISABLE_LINK");
15831
Hoonki Lee5305c3a2013-04-29 23:28:59 -070015832 if(TDLS_STA_INDEX_VALID(pTdlsPeer->staId))
Lee Hoonkic1262f22013-01-24 21:59:00 -080015833 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015834 long status;
15835
Pradeep Reddy POTTETIf3148e82015-04-16 12:10:33 +053015836 /* set tdls off channel status to false for this peer */
15837 pTdlsPeer->isOffChannelEstablished = FALSE;
Atul Mittal271a7652014-09-12 13:18:22 +053015838 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
15839 eTDLS_LINK_TEARING,
15840 (pTdlsPeer->link_status == eTDLS_LINK_TEARING)?
15841 eTDLS_LINK_UNSPECIFIED:
15842 eTDLS_LINK_DROPPED_BY_REMOTE);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015843 INIT_COMPLETION(pAdapter->tdls_del_station_comp);
15844
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015845 status = sme_DeleteTdlsPeerSta(
15846 WLAN_HDD_GET_HAL_CTX(pAdapter),
15847 pAdapter->sessionId, peer );
15848 if (status != VOS_STATUS_SUCCESS) {
15849 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to delete TDLS peer STA"));
15850 }
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015851
15852 status = wait_for_completion_interruptible_timeout(&pAdapter->tdls_del_station_comp,
15853 msecs_to_jiffies(WAIT_TIME_TDLS_DEL_STA));
Atul Mittal271a7652014-09-12 13:18:22 +053015854 wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
Atul Mittal454664b2014-10-10 11:03:46 +053015855 eTDLS_LINK_IDLE,
15856 eTDLS_LINK_UNSPECIFIED);
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015857 if (status <= 0)
15858 {
Gopichand Nakkalae7cbc5d2013-03-27 21:09:23 -070015859 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15860 "%s: Del station failed status %ld",
15861 __func__, status);
15862 return -EPERM;
15863 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015864
15865 /* TDLS Off Channel, Enable tdls channel switch,
15866 when their is only one tdls link and it supports */
15867 numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
15868 if (numCurrTdlsPeers == 1)
15869 {
15870 connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
15871 if ((connPeer) &&
15872 (connPeer->isOffChannelSupported == TRUE) &&
15873 (connPeer->isOffChannelConfigured == TRUE))
15874 {
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015875 connPeer->isOffChannelEstablished = TRUE;
Chandrasekaran, Manishekar0de84dc2015-03-10 15:12:34 +053015876 status = sme_SendTdlsChanSwitchReq(
15877 WLAN_HDD_GET_HAL_CTX(pAdapter),
15878 pAdapter->sessionId,
15879 connPeer->peerMac,
15880 connPeer->peerParams.channel,
15881 TDLS_OFF_CHANNEL_BW_OFFSET,
15882 TDLS_CHANNEL_SWITCH_ENABLE);
15883 if (status != VOS_STATUS_SUCCESS) {
15884 hddLog(VOS_TRACE_LEVEL_ERROR, FL("Failed to send TDLS switch channel req"));
15885 }
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015886 }
15887 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
15888 "%s: TDLS channel switch "
15889 "isOffChannelSupported %d "
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015890 "isOffChannelConfigured %d "
15891 "isOffChannelEstablished %d",
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015892 __func__,
15893 (connPeer ? connPeer->isOffChannelSupported : -1),
Pradeep Reddy POTTETI16d83332015-03-26 18:28:13 +053015894 (connPeer ? connPeer->isOffChannelConfigured : -1),
15895 (connPeer ? connPeer->isOffChannelEstablished : -1));
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015896 }
15897 else
15898 {
15899 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15900 "%s: TDLS channel switch request not sent "
15901 "numCurrTdlsPeers %d ",
15902 __func__, numCurrTdlsPeers);
15903 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015904 }
15905 else
15906 {
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015907 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15908 "%s: TDLS Peer Station doesn't exist.", __func__);
Lee Hoonkic1262f22013-01-24 21:59:00 -080015909 }
Lee Hoonkic1262f22013-01-24 21:59:00 -080015910 }
Gopichand Nakkalac87400e2013-03-13 18:51:00 -070015911 break;
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015912 case NL80211_TDLS_TEARDOWN:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015913 {
Atul Mittal115287b2014-07-08 13:26:33 +053015914 status = wlan_hdd_tdls_extctrl_deconfig_peer(pAdapter, peer);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015915
Atul Mittal115287b2014-07-08 13:26:33 +053015916 if (0 != status)
15917 {
15918 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015919 FL("Error in TDLS Teardown"));
Atul Mittal115287b2014-07-08 13:26:33 +053015920 return status;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015921 }
Sunil Dutt41de4e22013-11-14 18:09:02 +053015922 break;
15923 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015924 case NL80211_TDLS_SETUP:
Sunil Dutt41de4e22013-11-14 18:09:02 +053015925 {
Atul Mittal115287b2014-07-08 13:26:33 +053015926 status = wlan_hdd_tdls_extctrl_config_peer(pAdapter,
15927 peer,
Pradeep Reddy POTTETIe309c152015-02-06 13:21:07 +053015928 NULL,
Atul Mittal115287b2014-07-08 13:26:33 +053015929 NULL);
Sunil Dutt41de4e22013-11-14 18:09:02 +053015930
Atul Mittal115287b2014-07-08 13:26:33 +053015931 if (0 != status)
15932 {
15933 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015934 FL("Error in TDLS Setup"));
Atul Mittal115287b2014-07-08 13:26:33 +053015935 return status;
Naresh Jayaram937abdf2013-11-26 19:50:25 +053015936 }
Naresh Jayaramdb4514b2013-11-25 18:08:10 +053015937 break;
Sunil Dutt41de4e22013-11-14 18:09:02 +053015938 }
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015939 case NL80211_TDLS_DISCOVERY_REQ:
15940 /* We don't support in-driver setup/teardown/discovery */
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015941 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
Agarwal Ashisha7ef41d2015-06-25 18:00:26 +053015942 "%s: Driver doesn't support in-driver setup/teardown/discovery "
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015943 ,__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015944 return -ENOTSUPP;
15945 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053015946 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
15947 "%s: unsupported event",__func__);
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015948 return -ENOTSUPP;
15949 }
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053015950
15951 EXIT();
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015952 return 0;
15953}
Chilam NG571c65a2013-01-19 12:27:36 +053015954
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015955static int wlan_hdd_cfg80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015956#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
15957 const u8 *peer,
15958#else
15959 u8 *peer,
15960#endif
15961 enum nl80211_tdls_operation oper)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053015962{
15963 int ret;
15964
15965 vos_ssr_protect(__func__);
15966 ret = __wlan_hdd_cfg80211_tdls_oper(wiphy, dev, peer, oper);
15967 vos_ssr_unprotect(__func__);
15968
15969 return ret;
15970}
15971
Chilam NG571c65a2013-01-19 12:27:36 +053015972int wlan_hdd_cfg80211_send_tdls_discover_req(struct wiphy *wiphy,
15973 struct net_device *dev, u8 *peer)
15974{
Arif Hussaina7c8e412013-11-20 11:06:42 -080015975 hddLog(VOS_TRACE_LEVEL_INFO,
15976 "tdls send discover req: "MAC_ADDRESS_STR,
15977 MAC_ADDR_ARRAY(peer));
Chilam NG571c65a2013-01-19 12:27:36 +053015978
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015979#if TDLS_MGMT_VERSION2
15980 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15981 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
15982#else
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015983#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0))
15984 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15985 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, 0, NULL, 0);
15986#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,16,0))
15987 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15988 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
15989#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0))
15990 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15991 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, 0, NULL, 0);
15992#else
Chilam NG571c65a2013-01-19 12:27:36 +053015993 return wlan_hdd_cfg80211_tdls_mgmt(wiphy, dev, peer,
15994 WLAN_TDLS_DISCOVERY_REQUEST, 1, 0, NULL, 0);
Sunil Dutt Undekarieacac6f2014-03-21 14:08:53 +053015995#endif
Anand N Sunkad9bfc2622015-07-30 15:18:54 +053015996#endif /* KERNEL_VERSION */
Chilam NG571c65a2013-01-19 12:27:36 +053015997}
Mohit Khanna698ba2a2012-12-04 15:08:18 -080015998#endif
15999
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016000#ifdef WLAN_FEATURE_GTK_OFFLOAD
16001/*
16002 * FUNCTION: wlan_hdd_cfg80211_update_replayCounterCallback
16003 * Callback rountine called upon receiving response for
16004 * get offload info
16005 */
16006void wlan_hdd_cfg80211_update_replayCounterCallback(void *callbackContext,
16007 tpSirGtkOffloadGetInfoRspParams pGtkOffloadGetInfoRsp)
16008{
16009
16010 hdd_adapter_t *pAdapter = (hdd_adapter_t *)callbackContext;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016011 tANI_U8 tempReplayCounter[8];
16012 hdd_station_ctx_t *pHddStaCtx;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016013
16014 ENTER();
16015
16016 if (NULL == pAdapter)
16017 {
Agarwal Ashish971c2882013-10-30 20:11:12 +053016018 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016019 "%s: HDD adapter is Null", __func__);
16020 return ;
16021 }
16022
16023 if (NULL == pGtkOffloadGetInfoRsp)
16024 {
16025 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16026 "%s: pGtkOffloadGetInfoRsp is Null", __func__);
16027 return ;
16028 }
16029
16030 if (VOS_STATUS_SUCCESS != pGtkOffloadGetInfoRsp->ulStatus)
16031 {
16032 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16033 "%s: wlan Failed to get replay counter value",
16034 __func__);
16035 return ;
16036 }
16037
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016038 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16039 /* Update replay counter */
16040 pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter =
16041 pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16042
16043 {
16044 /* changing from little to big endian since supplicant
16045 * works on big endian format
16046 */
16047 int i;
16048 tANI_U8 *p = (tANI_U8 *)&pGtkOffloadGetInfoRsp->ullKeyReplayCounter;
16049
16050 for (i = 0; i < 8; i++)
16051 {
16052 tempReplayCounter[7-i] = (tANI_U8)p[i];
16053 }
16054 }
16055
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016056 /* Update replay counter to NL */
16057 cfg80211_gtk_rekey_notify(pAdapter->dev, pGtkOffloadGetInfoRsp->bssId,
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016058 tempReplayCounter, GFP_KERNEL);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016059}
16060
16061/*
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016062 * FUNCTION: __wlan_hdd_cfg80211_set_rekey_data
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016063 * This function is used to offload GTK rekeying job to the firmware.
16064 */
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016065int __wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016066 struct cfg80211_gtk_rekey_data *data)
16067{
16068 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16069 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16070 hdd_station_ctx_t *pHddStaCtx;
16071 tHalHandle hHal;
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016072 int result;
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016073 tSirGtkOffloadParams hddGtkOffloadReqParams;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016074 eHalStatus status = eHAL_STATUS_FAILURE;
16075
16076 ENTER();
16077
16078 if (NULL == pAdapter)
16079 {
Kaushik, Sushantb1ed0f42014-07-01 18:26:31 +053016080 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016081 "%s: HDD adapter is Null", __func__);
16082 return -ENODEV;
16083 }
16084
Sushant Kaushik4b7cb302014-01-06 17:45:01 +053016085 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16086 TRACE_CODE_HDD_CFG80211_SET_REKEY_DATA,
16087 pAdapter->sessionId, pAdapter->device_mode));
16088
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016089 result = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016090 if (0 != result)
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016091 {
Gopichand Nakkalaf502e2b2013-05-24 18:34:25 +053016092 return result;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016093 }
16094
16095 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16096 hHal = WLAN_HDD_GET_HAL_CTX(pAdapter);
16097 if (NULL == hHal)
16098 {
16099 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16100 "%s: HAL context is Null!!!", __func__);
16101 return -EAGAIN;
16102 }
16103
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016104 pHddStaCtx->gtkOffloadReqParams.ulFlags = GTK_OFFLOAD_ENABLE;
16105 memcpy(pHddStaCtx->gtkOffloadReqParams.aKCK, data->kck, NL80211_KCK_LEN);
16106 memcpy(pHddStaCtx->gtkOffloadReqParams.aKEK, data->kek, NL80211_KEK_LEN);
16107 memcpy(pHddStaCtx->gtkOffloadReqParams.bssId, &pHddStaCtx->conn_info.bssId,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016108 WNI_CFG_BSSID_LEN);
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016109 {
16110 /* changing from big to little endian since driver
16111 * works on little endian format
16112 */
16113 tANI_U8 *p =
16114 (tANI_U8 *)&pHddStaCtx->gtkOffloadReqParams.ullKeyReplayCounter;
16115 int i;
16116
16117 for (i = 0; i < 8; i++)
16118 {
16119 p[7-i] = data->replay_ctr[i];
16120 }
16121 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016122
16123 if (TRUE == pHddCtx->hdd_wlan_suspended)
16124 {
16125 /* if wlan is suspended, enable GTK offload directly from here */
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016126 memcpy(&hddGtkOffloadReqParams, &pHddStaCtx->gtkOffloadReqParams,
16127 sizeof (tSirGtkOffloadParams));
16128 status = sme_SetGTKOffload(hHal, &hddGtkOffloadReqParams,
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016129 pAdapter->sessionId);
16130
16131 if (eHAL_STATUS_SUCCESS != status)
16132 {
16133 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16134 "%s: sme_SetGTKOffload failed, returned %d",
16135 __func__, status);
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016136
16137 /* Need to clear any trace of key value in the memory.
16138 * Thus zero out the memory even though it is local
16139 * variable.
16140 */
16141 vos_mem_zero(&hddGtkOffloadReqParams,
16142 sizeof(hddGtkOffloadReqParams));
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016143 return status;
16144 }
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016145 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16146 "%s: sme_SetGTKOffload successfull", __func__);
16147 }
16148 else
16149 {
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016150 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16151 "%s: wlan not suspended GTKOffload request is stored",
16152 __func__);
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016153 }
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016154
Vinay Krishna Eranna6f22c1f2014-10-13 16:03:06 +053016155 /* Need to clear any trace of key value in the memory.
16156 * Thus zero out the memory even though it is local
16157 * variable.
16158 */
16159 vos_mem_zero(&hddGtkOffloadReqParams,
16160 sizeof(hddGtkOffloadReqParams));
16161
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016162 EXIT();
Gopichand Nakkalad36ee622013-05-07 14:13:27 +053016163 return eHAL_STATUS_SUCCESS;
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016164}
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016165
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016166int wlan_hdd_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *dev,
16167 struct cfg80211_gtk_rekey_data *data)
16168{
16169 int ret;
16170
16171 vos_ssr_protect(__func__);
16172 ret = __wlan_hdd_cfg80211_set_rekey_data(wiphy, dev, data);
16173 vos_ssr_unprotect(__func__);
16174
16175 return ret;
16176}
16177#endif /*WLAN_FEATURE_GTK_OFFLOAD*/
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016178/*
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016179 * FUNCTION: __wlan_hdd_cfg80211_set_mac_acl
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016180 * This function is used to set access control policy
16181 */
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016182static int __wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
16183 struct net_device *dev,
16184 const struct cfg80211_acl_data *params)
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016185{
16186 int i;
16187 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16188 hdd_hostapd_state_t *pHostapdState;
16189 tsap_Config_t *pConfig;
16190 v_CONTEXT_t pVosContext = NULL;
16191 hdd_context_t *pHddCtx;
16192 int status;
16193
16194 ENTER();
16195
16196 if (NULL == pAdapter)
16197 {
16198 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16199 "%s: HDD adapter is Null", __func__);
16200 return -ENODEV;
16201 }
16202
16203 if (NULL == params)
16204 {
16205 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16206 "%s: params is Null", __func__);
16207 return -EINVAL;
16208 }
16209
16210 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16211 status = wlan_hdd_validate_context(pHddCtx);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016212 if (0 != status)
16213 {
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016214 return status;
16215 }
16216
16217 pVosContext = pHddCtx->pvosContext;
16218 pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pAdapter);
16219
16220 if (NULL == pHostapdState)
16221 {
16222 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16223 "%s: pHostapdState is Null", __func__);
16224 return -EINVAL;
16225 }
16226
16227 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,"acl policy: = %d"
16228 "no acl entries = %d", params->acl_policy, params->n_acl_entries);
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016229 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16230 TRACE_CODE_HDD_CFG80211_SET_MAC_ACL,
16231 pAdapter->sessionId, pAdapter->device_mode));
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016232
16233 if (WLAN_HDD_SOFTAP == pAdapter->device_mode)
16234 {
16235 pConfig = &pAdapter->sessionCtx.ap.sapConfig;
16236
16237 /* default value */
16238 pConfig->num_accept_mac = 0;
16239 pConfig->num_deny_mac = 0;
16240
16241 /**
16242 * access control policy
16243 * @NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED: Deny stations which are
16244 * listed in hostapd.deny file.
16245 * @NL80211_ACL_POLICY_DENY_UNLESS_LISTED: Allow stations which are
16246 * listed in hostapd.accept file.
16247 */
16248 if (NL80211_ACL_POLICY_DENY_UNLESS_LISTED == params->acl_policy)
16249 {
16250 pConfig->SapMacaddr_acl = eSAP_DENY_UNLESS_ACCEPTED;
16251 }
16252 else if (NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED == params->acl_policy)
16253 {
16254 pConfig->SapMacaddr_acl = eSAP_ACCEPT_UNLESS_DENIED;
16255 }
16256 else
16257 {
16258 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16259 "%s:Acl Policy : %d is not supported",
16260 __func__, params->acl_policy);
16261 return -ENOTSUPP;
16262 }
16263
16264 if (eSAP_DENY_UNLESS_ACCEPTED == pConfig->SapMacaddr_acl)
16265 {
16266 pConfig->num_accept_mac = params->n_acl_entries;
16267 for (i = 0; i < params->n_acl_entries; i++)
16268 {
16269 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16270 "** Add ACL MAC entry %i in WhiletList :"
16271 MAC_ADDRESS_STR, i,
16272 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
16273
16274 vos_mem_copy(&pConfig->accept_mac[i], params->mac_addrs[i].addr,
16275 sizeof(qcmacaddr));
16276 }
16277 }
16278 else if (eSAP_ACCEPT_UNLESS_DENIED == pConfig->SapMacaddr_acl)
16279 {
16280 pConfig->num_deny_mac = params->n_acl_entries;
16281 for (i = 0; i < params->n_acl_entries; i++)
16282 {
16283 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16284 "** Add ACL MAC entry %i in BlackList :"
16285 MAC_ADDRESS_STR, i,
16286 MAC_ADDR_ARRAY(params->mac_addrs[i].addr));
16287
16288 vos_mem_copy(&pConfig->deny_mac[i], params->mac_addrs[i].addr,
16289 sizeof(qcmacaddr));
16290 }
16291 }
16292
16293 if (VOS_STATUS_SUCCESS != WLANSAP_SetMacACL(pVosContext, pConfig))
16294 {
16295 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16296 "%s: SAP Set Mac Acl fail", __func__);
16297 return -EINVAL;
16298 }
16299 }
16300 else
16301 {
16302 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Sushant Kaushik8bc7df22014-04-09 17:55:29 +053016303 "%s: Invalid device_mode = %s (%d)",
16304 __func__, hdd_device_modetoString(pAdapter->device_mode),
16305 pAdapter->device_mode);
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016306 return -EINVAL;
16307 }
16308
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016309 EXIT();
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016310 return 0;
16311}
16312
Mahesh A Saptasagard68eb282014-12-17 14:20:19 +053016313static int wlan_hdd_cfg80211_set_mac_acl(struct wiphy *wiphy,
16314 struct net_device *dev,
16315 const struct cfg80211_acl_data *params)
16316{
16317 int ret;
16318 vos_ssr_protect(__func__);
16319 ret = __wlan_hdd_cfg80211_set_mac_acl(wiphy, dev, params);
16320 vos_ssr_unprotect(__func__);
16321
16322 return ret;
16323}
16324
Leo Chang9056f462013-08-01 19:21:11 -070016325#ifdef WLAN_NL80211_TESTMODE
16326#ifdef FEATURE_WLAN_LPHB
Leo Changd9df8aa2013-09-26 13:32:26 -070016327void wlan_hdd_cfg80211_lphb_ind_handler
Leo Chang9056f462013-08-01 19:21:11 -070016328(
16329 void *pAdapter,
16330 void *indCont
16331)
16332{
Leo Changd9df8aa2013-09-26 13:32:26 -070016333 tSirLPHBInd *lphbInd;
16334 struct sk_buff *skb;
c_hpothu73f35e62014-04-18 13:40:08 +053016335 hdd_context_t *pHddCtxt;
Leo Chang9056f462013-08-01 19:21:11 -070016336
16337 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016338 "LPHB indication arrived");
Leo Chang9056f462013-08-01 19:21:11 -070016339
c_hpothu73f35e62014-04-18 13:40:08 +053016340 if (pAdapter == NULL)
16341 {
16342 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16343 "%s: pAdapter is NULL\n",__func__);
16344 return;
16345 }
16346
Leo Chang9056f462013-08-01 19:21:11 -070016347 if (NULL == indCont)
16348 {
16349 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
Leo Changd9df8aa2013-09-26 13:32:26 -070016350 "LPHB IND, invalid argument");
Leo Chang9056f462013-08-01 19:21:11 -070016351 return;
16352 }
16353
c_hpothu73f35e62014-04-18 13:40:08 +053016354 pHddCtxt = (hdd_context_t *)pAdapter;
Leo Changd9df8aa2013-09-26 13:32:26 -070016355 lphbInd = (tSirLPHBInd *)indCont;
Leo Chang9056f462013-08-01 19:21:11 -070016356 skb = cfg80211_testmode_alloc_event_skb(
c_hpothu73f35e62014-04-18 13:40:08 +053016357 pHddCtxt->wiphy,
Leo Changd9df8aa2013-09-26 13:32:26 -070016358 sizeof(tSirLPHBInd),
Leo Chang9056f462013-08-01 19:21:11 -070016359 GFP_ATOMIC);
16360 if (!skb)
16361 {
16362 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16363 "LPHB timeout, NL buffer alloc fail");
16364 return;
16365 }
16366
Leo Changac3ba772013-10-07 09:47:04 -070016367 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_CMD, WLAN_HDD_TM_CMD_WLAN_HB))
Leo Changd9df8aa2013-09-26 13:32:26 -070016368 {
16369 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16370 "WLAN_HDD_TM_ATTR_CMD put fail");
16371 goto nla_put_failure;
16372 }
Leo Changac3ba772013-10-07 09:47:04 -070016373 if(nla_put_u32(skb, WLAN_HDD_TM_ATTR_TYPE, lphbInd->protocolType))
Leo Changd9df8aa2013-09-26 13:32:26 -070016374 {
16375 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16376 "WLAN_HDD_TM_ATTR_TYPE put fail");
16377 goto nla_put_failure;
16378 }
Leo Changac3ba772013-10-07 09:47:04 -070016379 if(nla_put(skb, WLAN_HDD_TM_ATTR_DATA,
Leo Changd9df8aa2013-09-26 13:32:26 -070016380 sizeof(tSirLPHBInd), lphbInd))
16381 {
16382 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16383 "WLAN_HDD_TM_ATTR_DATA put fail");
16384 goto nla_put_failure;
16385 }
Leo Chang9056f462013-08-01 19:21:11 -070016386 cfg80211_testmode_event(skb, GFP_ATOMIC);
16387 return;
16388
16389nla_put_failure:
16390 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16391 "NLA Put fail");
16392 kfree_skb(skb);
16393
16394 return;
16395}
16396#endif /* FEATURE_WLAN_LPHB */
16397
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016398static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
Leo Chang9056f462013-08-01 19:21:11 -070016399{
16400 struct nlattr *tb[WLAN_HDD_TM_ATTR_MAX + 1];
16401 int err = 0;
16402#ifdef FEATURE_WLAN_LPHB
16403 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Leo Changd9df8aa2013-09-26 13:32:26 -070016404 eHalStatus smeStatus;
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016405
16406 ENTER();
16407
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016408 err = wlan_hdd_validate_context(pHddCtx);
16409 if (0 != err)
16410 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016411 return err;
16412 }
Leo Chang9056f462013-08-01 19:21:11 -070016413#endif /* FEATURE_WLAN_LPHB */
16414
16415 err = nla_parse(tb, WLAN_HDD_TM_ATTR_MAX, data, len, wlan_hdd_tm_policy);
16416 if (err)
16417 {
16418 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16419 "%s Testmode INV ATTR", __func__);
16420 return err;
16421 }
16422
16423 if (!tb[WLAN_HDD_TM_ATTR_CMD])
16424 {
16425 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16426 "%s Testmode INV CMD", __func__);
16427 return -EINVAL;
16428 }
16429
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016430 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16431 TRACE_CODE_HDD_CFG80211_TESTMODE,
16432 NO_SESSION, nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD])));
Leo Chang9056f462013-08-01 19:21:11 -070016433 switch (nla_get_u32(tb[WLAN_HDD_TM_ATTR_CMD]))
16434 {
16435#ifdef FEATURE_WLAN_LPHB
16436 /* Low Power Heartbeat configuration request */
16437 case WLAN_HDD_TM_CMD_WLAN_HB:
16438 {
16439 int buf_len;
16440 void *buf;
16441 tSirLPHBReq *hb_params = NULL;
Amar Singhal05852702014-02-04 14:40:00 -080016442 tSirLPHBReq *hb_params_temp = NULL;
Leo Chang9056f462013-08-01 19:21:11 -070016443
16444 if (!tb[WLAN_HDD_TM_ATTR_DATA])
16445 {
16446 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16447 "%s Testmode INV DATA", __func__);
16448 return -EINVAL;
16449 }
16450
16451 buf = nla_data(tb[WLAN_HDD_TM_ATTR_DATA]);
16452 buf_len = nla_len(tb[WLAN_HDD_TM_ATTR_DATA]);
Amar Singhal05852702014-02-04 14:40:00 -080016453
16454 hb_params_temp =(tSirLPHBReq *)buf;
16455 if ((hb_params_temp->cmd == LPHB_SET_TCP_PARAMS_INDID) &&
16456 (hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
16457 return -EINVAL;
16458
Leo Chang9056f462013-08-01 19:21:11 -070016459 hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
16460 if (NULL == hb_params)
16461 {
16462 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16463 "%s Request Buffer Alloc Fail", __func__);
16464 return -EINVAL;
16465 }
16466
16467 vos_mem_copy(hb_params, buf, buf_len);
Leo Changd9df8aa2013-09-26 13:32:26 -070016468 smeStatus = sme_LPHBConfigReq((tHalHandle)(pHddCtx->hHal),
16469 hb_params,
16470 wlan_hdd_cfg80211_lphb_ind_handler);
16471 if (eHAL_STATUS_SUCCESS != smeStatus)
Leo Chang9056f462013-08-01 19:21:11 -070016472 {
Leo Changd9df8aa2013-09-26 13:32:26 -070016473 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16474 "LPHB Config Fail, disable");
Leo Chang9056f462013-08-01 19:21:11 -070016475 vos_mem_free(hb_params);
16476 }
Leo Chang9056f462013-08-01 19:21:11 -070016477 return 0;
16478 }
16479#endif /* FEATURE_WLAN_LPHB */
16480 default:
c_hpothu6ff1c3c2013-10-01 19:01:57 +053016481 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
16482 "%s: unsupported event",__func__);
Leo Chang9056f462013-08-01 19:21:11 -070016483 return -EOPNOTSUPP;
16484 }
16485
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016486 EXIT();
16487 return err;
Leo Chang9056f462013-08-01 19:21:11 -070016488}
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016489
Anand N Sunkade9adb1b2015-07-29 09:56:45 +053016490static int wlan_hdd_cfg80211_testmode(struct wiphy *wiphy,
16491#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
16492 struct wireless_dev *wdev,
16493#endif
16494 void *data, int len)
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016495{
16496 int ret;
16497
16498 vos_ssr_protect(__func__);
16499 ret = __wlan_hdd_cfg80211_testmode(wiphy, data, len);
16500 vos_ssr_unprotect(__func__);
16501
16502 return ret;
16503}
Leo Chang9056f462013-08-01 19:21:11 -070016504#endif /* CONFIG_NL80211_TESTMODE */
16505
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016506static int __wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016507 struct net_device *dev,
16508 int idx, struct survey_info *survey)
16509{
16510 hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev);
16511 hdd_context_t *pHddCtx;
Mihir Sheted9072e02013-08-21 17:02:29 +053016512 hdd_station_ctx_t *pHddStaCtx;
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016513 tHalHandle halHandle;
Mihir Sheted9072e02013-08-21 17:02:29 +053016514 v_U32_t channel = 0, freq = 0; /* Initialization Required */
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016515 v_S7_t snr,rssi;
16516 int status, i, j, filled = 0;
16517
16518 ENTER();
16519
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016520 if (NULL == pAdapter)
16521 {
16522 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16523 "%s: HDD adapter is Null", __func__);
16524 return -ENODEV;
16525 }
16526
16527 if (NULL == wiphy)
16528 {
16529 VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_FATAL,
16530 "%s: wiphy is Null", __func__);
16531 return -ENODEV;
16532 }
16533
16534 pHddCtx = WLAN_HDD_GET_CTX(pAdapter);
16535 status = wlan_hdd_validate_context(pHddCtx);
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016536 if (0 != status)
16537 {
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016538 return status;
16539 }
16540
Mihir Sheted9072e02013-08-21 17:02:29 +053016541 pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
16542
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016543 if (0 == pHddCtx->cfg_ini->fEnableSNRMonitoring ||
Mihir Sheted9072e02013-08-21 17:02:29 +053016544 0 != pAdapter->survey_idx ||
16545 eConnectionState_Associated != pHddStaCtx->conn_info.connState)
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016546 {
16547 /* The survey dump ops when implemented completely is expected to
16548 * return a survey of all channels and the ops is called by the
16549 * kernel with incremental values of the argument 'idx' till it
16550 * returns -ENONET. But we can only support the survey for the
16551 * operating channel for now. survey_idx is used to track
16552 * that the ops is called only once and then return -ENONET for
16553 * the next iteration
16554 */
16555 pAdapter->survey_idx = 0;
16556 return -ENONET;
16557 }
16558
Mukul Sharma9d5233b2015-06-11 20:28:20 +053016559 if (VOS_TRUE == pHddStaCtx->hdd_ReassocScenario)
16560 {
16561 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16562 "%s: Roaming in progress, hence return ", __func__);
16563 return -ENONET;
16564 }
16565
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016566 halHandle = WLAN_HDD_GET_HAL_CTX(pAdapter);
16567
16568 wlan_hdd_get_snr(pAdapter, &snr);
16569 wlan_hdd_get_rssi(pAdapter, &rssi);
16570
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016571 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16572 TRACE_CODE_HDD_CFG80211_DUMP_SURVEY,
16573 pAdapter->sessionId, pAdapter->device_mode));
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016574 sme_GetOperationChannel(halHandle, &channel, pAdapter->sessionId);
16575 hdd_wlan_get_freq(channel, &freq);
16576
16577
16578 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
16579 {
16580 if (NULL == wiphy->bands[i])
16581 {
16582 VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_INFO,
16583 "%s: wiphy->bands[i] is NULL, i = %d", __func__, i);
16584 continue;
16585 }
16586
16587 for (j = 0; j < wiphy->bands[i]->n_channels; j++)
16588 {
16589 struct ieee80211_supported_band *band = wiphy->bands[i];
16590
16591 if (band->channels[j].center_freq == (v_U16_t)freq)
16592 {
16593 survey->channel = &band->channels[j];
16594 /* The Rx BDs contain SNR values in dB for the received frames
16595 * while the supplicant expects noise. So we calculate and
16596 * return the value of noise (dBm)
16597 * SNR (dB) = RSSI (dBm) - NOISE (dBm)
16598 */
16599 survey->noise = rssi - snr;
16600 survey->filled = SURVEY_INFO_NOISE_DBM;
16601 filled = 1;
16602 }
16603 }
16604 }
16605
16606 if (filled)
16607 pAdapter->survey_idx = 1;
16608 else
16609 {
16610 pAdapter->survey_idx = 0;
16611 return -ENONET;
16612 }
16613
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016614 EXIT();
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016615 return 0;
16616}
16617
Mahesh A Saptasagar27574072014-06-17 13:39:04 +053016618static int wlan_hdd_cfg80211_dump_survey(struct wiphy *wiphy,
16619 struct net_device *dev,
16620 int idx, struct survey_info *survey)
16621{
16622 int ret;
16623
16624 vos_ssr_protect(__func__);
16625 ret = __wlan_hdd_cfg80211_dump_survey(wiphy, dev, idx, survey);
16626 vos_ssr_unprotect(__func__);
16627
16628 return ret;
16629}
16630
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016631/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016632 * FUNCTION: __wlan_hdd_cfg80211_resume_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016633 * this is called when cfg80211 driver resume
16634 * driver updates latest sched_scan scan result(if any) to cfg80211 database
16635 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016636int __wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016637{
16638 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
16639 hdd_adapter_t *pAdapter;
16640 hdd_adapter_list_node_t *pAdapterNode, *pNext;
16641 VOS_STATUS status = VOS_STATUS_SUCCESS;
16642
16643 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016644
Mahesh A Saptasagar74088392015-02-05 17:22:09 +053016645 if (0 != wlan_hdd_validate_context(pHddCtx))
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016646 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016647 return 0;
16648 }
16649
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016650 MTRACE(vos_trace(VOS_MODULE_ID_HDD, TRACE_CODE_HDD_CFG80211_RESUME_WLAN,
16651 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016652 spin_lock(&pHddCtx->schedScan_lock);
16653 pHddCtx->isWiphySuspended = FALSE;
16654 if (TRUE != pHddCtx->isSchedScanUpdatePending)
16655 {
16656 spin_unlock(&pHddCtx->schedScan_lock);
16657 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16658 "%s: Return resume is not due to PNO indication", __func__);
16659 return 0;
16660 }
16661 // Reset flag to avoid updatating cfg80211 data old results again
16662 pHddCtx->isSchedScanUpdatePending = FALSE;
16663 spin_unlock(&pHddCtx->schedScan_lock);
16664
16665 status = hdd_get_front_adapter ( pHddCtx, &pAdapterNode );
16666
16667 while ( NULL != pAdapterNode && VOS_STATUS_SUCCESS == status )
16668 {
16669 pAdapter = pAdapterNode->pAdapter;
16670 if ( (NULL != pAdapter) &&
16671 (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) )
16672 {
16673 if (0 != wlan_hdd_cfg80211_update_bss(pHddCtx->wiphy, pAdapter))
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016674 {
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016675 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN,
16676 "%s: NO SCAN result", __func__);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016677 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016678 else
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016679 {
16680 /* Acquire wakelock to handle the case where APP's tries to
16681 * suspend immediately after updating the scan results. Whis
16682 * results in app's is in suspended state and not able to
16683 * process the connect request to AP
16684 */
Sushant Kaushik83392fa2015-05-05 17:44:40 +053016685 hdd_prevent_suspend_timeout(2000,
16686 WIFI_POWER_EVENT_WAKELOCK_RESUME_WLAN);
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016687 cfg80211_sched_scan_results(pHddCtx->wiphy);
Mahesh A Saptasagarb9c50402014-01-16 15:49:22 +053016688 }
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016689
16690 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16691 "%s : cfg80211 scan result database updated", __func__);
16692
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016693 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016694 return 0;
16695
16696 }
16697 status = hdd_get_next_adapter ( pHddCtx, pAdapterNode, &pNext );
16698 pAdapterNode = pNext;
16699 }
16700
16701 VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
16702 "%s: Failed to find Adapter", __func__);
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016703 EXIT();
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016704 return 0;
16705}
16706
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016707int wlan_hdd_cfg80211_resume_wlan(struct wiphy *wiphy)
16708{
16709 int ret;
16710
16711 vos_ssr_protect(__func__);
16712 ret = __wlan_hdd_cfg80211_resume_wlan(wiphy);
16713 vos_ssr_unprotect(__func__);
16714
16715 return ret;
16716}
16717
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016718/*
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016719 * FUNCTION: __wlan_hdd_cfg80211_suspend_wlan
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016720 * this is called when cfg80211 driver suspends
16721 */
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016722int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016723 struct cfg80211_wowlan *wow)
16724{
16725 hdd_context_t *pHddCtx = wiphy_priv(wiphy);
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016726 int ret = 0;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016727
16728 ENTER();
Hanumantha Reddy Pothula7dc0e6c2015-03-06 15:11:16 +053016729
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016730 ret = wlan_hdd_validate_context(pHddCtx);
16731 if (0 != ret)
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016732 {
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016733 return ret;
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016734 }
16735
Masti, Narayanraddic80e2bf2015-01-27 16:39:00 +053016736
Konamki, Sreelakshmi7b464be2015-07-14 12:17:01 +053016737 MTRACE(vos_trace(VOS_MODULE_ID_HDD,
16738 TRACE_CODE_HDD_CFG80211_SUSPEND_WLAN,
16739 NO_SESSION, pHddCtx->isWiphySuspended));
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016740 pHddCtx->isWiphySuspended = TRUE;
16741
16742 EXIT();
16743
16744 return 0;
16745}
16746
Mahesh A Saptasagarbcc5b662014-06-02 21:46:23 +053016747int wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy,
16748 struct cfg80211_wowlan *wow)
16749{
16750 int ret;
16751
16752 vos_ssr_protect(__func__);
16753 ret = __wlan_hdd_cfg80211_suspend_wlan(wiphy, wow);
16754 vos_ssr_unprotect(__func__);
16755
16756 return ret;
16757}
Jeff Johnson295189b2012-06-20 16:38:30 -070016758/* cfg80211_ops */
Gopichand Nakkala747461f2013-04-24 19:24:45 +053016759static struct cfg80211_ops wlan_hdd_cfg80211_ops =
Jeff Johnson295189b2012-06-20 16:38:30 -070016760{
16761 .add_virtual_intf = wlan_hdd_add_virtual_intf,
16762 .del_virtual_intf = wlan_hdd_del_virtual_intf,
16763 .change_virtual_intf = wlan_hdd_cfg80211_change_iface,
16764 .change_station = wlan_hdd_change_station,
16765#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
16766 .add_beacon = wlan_hdd_cfg80211_add_beacon,
16767 .del_beacon = wlan_hdd_cfg80211_del_beacon,
16768 .set_beacon = wlan_hdd_cfg80211_set_beacon,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016769#else
16770 .start_ap = wlan_hdd_cfg80211_start_ap,
16771 .change_beacon = wlan_hdd_cfg80211_change_beacon,
16772 .stop_ap = wlan_hdd_cfg80211_stop_ap,
Jeff Johnson295189b2012-06-20 16:38:30 -070016773#endif
16774 .change_bss = wlan_hdd_cfg80211_change_bss,
16775 .add_key = wlan_hdd_cfg80211_add_key,
16776 .get_key = wlan_hdd_cfg80211_get_key,
16777 .del_key = wlan_hdd_cfg80211_del_key,
16778 .set_default_key = wlan_hdd_cfg80211_set_default_key,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080016779#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0))
Jeff Johnson295189b2012-06-20 16:38:30 -070016780 .set_channel = wlan_hdd_cfg80211_set_channel,
Jeff Johnson3bbe4bf2013-01-18 17:05:29 -080016781#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016782 .scan = wlan_hdd_cfg80211_scan,
16783 .connect = wlan_hdd_cfg80211_connect,
16784 .disconnect = wlan_hdd_cfg80211_disconnect,
16785 .join_ibss = wlan_hdd_cfg80211_join_ibss,
16786 .leave_ibss = wlan_hdd_cfg80211_leave_ibss,
16787 .set_wiphy_params = wlan_hdd_cfg80211_set_wiphy_params,
16788 .set_tx_power = wlan_hdd_cfg80211_set_txpower,
16789 .get_tx_power = wlan_hdd_cfg80211_get_txpower,
Jeff Johnson295189b2012-06-20 16:38:30 -070016790 .remain_on_channel = wlan_hdd_cfg80211_remain_on_channel,
16791 .cancel_remain_on_channel = wlan_hdd_cfg80211_cancel_remain_on_channel,
DARAM SUDHA39eede62014-02-12 11:16:40 +053016792 .mgmt_tx = wlan_hdd_mgmt_tx,
Jeff Johnson295189b2012-06-20 16:38:30 -070016793#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
16794 .mgmt_tx_cancel_wait = wlan_hdd_cfg80211_mgmt_tx_cancel_wait,
16795 .set_default_mgmt_key = wlan_hdd_set_default_mgmt_key,
16796 .set_txq_params = wlan_hdd_set_txq_params,
16797#endif
Jeff Johnson295189b2012-06-20 16:38:30 -070016798 .get_station = wlan_hdd_cfg80211_get_station,
16799 .set_power_mgmt = wlan_hdd_cfg80211_set_power_mgmt,
16800 .del_station = wlan_hdd_cfg80211_del_station,
Jeff Johnson04dd8a82012-06-29 20:41:40 -070016801 .add_station = wlan_hdd_cfg80211_add_station,
16802#ifdef FEATURE_WLAN_LFR
16803 .set_pmksa = wlan_hdd_cfg80211_set_pmksa,
16804 .del_pmksa = wlan_hdd_cfg80211_del_pmksa,
16805 .flush_pmksa = wlan_hdd_cfg80211_flush_pmksa,
16806#endif
Madan Mohan Koyyalamudiea773882012-11-02 13:37:21 -070016807#if defined(WLAN_FEATURE_VOWIFI_11R) && defined(KERNEL_SUPPORT_11R_CFG80211)
16808 .update_ft_ies = wlan_hdd_cfg80211_update_ft_ies,
16809#endif
Mohit Khanna698ba2a2012-12-04 15:08:18 -080016810#ifdef FEATURE_WLAN_TDLS
16811 .tdls_mgmt = wlan_hdd_cfg80211_tdls_mgmt,
16812 .tdls_oper = wlan_hdd_cfg80211_tdls_oper,
16813#endif
Gopichand Nakkala870cbae2013-03-15 21:16:09 +053016814#ifdef WLAN_FEATURE_GTK_OFFLOAD
16815 .set_rekey_data = wlan_hdd_cfg80211_set_rekey_data,
16816#endif /* WLAN_FEATURE_GTK_OFFLOAD */
Gopichand Nakkala8e93fde2013-05-10 17:40:12 +053016817#ifdef FEATURE_WLAN_SCAN_PNO
16818 .sched_scan_start = wlan_hdd_cfg80211_sched_scan_start,
16819 .sched_scan_stop = wlan_hdd_cfg80211_sched_scan_stop,
16820#endif /*FEATURE_WLAN_SCAN_PNO */
Kamath Vinayak4000c9a2013-08-23 14:24:27 +053016821 .resume = wlan_hdd_cfg80211_resume_wlan,
16822 .suspend = wlan_hdd_cfg80211_suspend_wlan,
Gopichand Nakkalac005b7c2013-05-14 16:04:14 +053016823 .set_mac_acl = wlan_hdd_cfg80211_set_mac_acl,
Leo Chang9056f462013-08-01 19:21:11 -070016824#ifdef WLAN_NL80211_TESTMODE
16825 .testmode_cmd = wlan_hdd_cfg80211_testmode,
16826#endif
Madan Mohan Koyyalamudid9383fd2013-08-13 09:27:30 +053016827 .dump_survey = wlan_hdd_cfg80211_dump_survey,
Jeff Johnson295189b2012-06-20 16:38:30 -070016828};
16829